ASP.net Blazor:显示来自两个或多个相关表的数据



https://www.youtube.com/watch?v=UBNRcaw1bDk&list=PL6n9fhu94yhVowClAs8-6nYnfsOTma14P&索引=23

嗨,我正在努力实现上面链接中提到的项目。我正在尝试从ASP.NET WebAPI项目中获取数据,并在Blazor项目中消费。我从单个表中检索数据没有问题。但当我尝试从Secondary表中检索数据时。我在下面得到错误:

"HttpRequestException:响应状态代码未指示成功:500(内部服务器错误(">

在发送之前,我尝试将结果(在API项目中(显式强制转换为"Employee"类。没用。API上的调试清楚地显示返回的员工有部门信息,但在收到错误时,在Blazor项目上。提前感谢!!

更新:

感谢大家的帮助。这是原始代码。

Models:
   public class Employee
    {
        public int EmployeeId { get; set; }
        [Required]
        [MinLength(2)]
        public string FirstName { get; set; }
        [Required]
        public string LastName { get; set; }
        public string Email { get; set; }
        public DateTime DateOfBrith { get; set; }
        public Gender Gender { get; set; }
        public int DepartmentId { get; set; }
        public Department Department { get; set; }
        public string PhotoPath { get; set; }
    }
    public class Department
    {
        public int DepartmentId { get; set; }
        public string DepartmentName { get; set; }
    }
EF:
public class EmployeeRepository : IEmployeeRepository
    {
    private readonly AppDbContext appDbContext;
    public EmployeeRepository(AppDbContext appDbContext)
    {
        this.appDbContext = appDbContext;
    }

    public async Task<Employee> GetEmployee(int employeeId)
    {
  // If I don't include Department table. I'm able to retrieve employee table data fine in Blazor project
        return await appDbContext.Employees
            .Include(e => e.Department)
            .FirstOrDefaultAsync(e => e.EmployeeId == employeeId);
    }
   }
API:
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeesController : ControllerBase
    {
        private readonly IEmployeeRepository employeeRepository;
        public EmployeesController(IEmployeeRepository employeeRepository)
        {
            this.employeeRepository = employeeRepository;
        }
        [HttpGet("{id:int}")]
            public async Task<ActionResult<Employee>> GetEmployee(int id)
            {
                try
                {
    
                    var result = await employeeRepository.GetEmployee(id);
    
                    if (result == null) return NotFound();
    //Breakpoint here returns data perfectly fine . With or without cast
                    return Ok(result);
                }
                catch (Exception)
                {
                    return StatusCode(StatusCodes.Status500InternalServerError,
                        "Error retrieving data from the database");
                }
            }
        }
 Call API in Blazor
 //Service 
 public interface IEmployeeService
 {
    Task<Employee> GetEmployee(int id);
 }
 public class EmployeeService : IEmployeeService
    {
        private readonly HttpClient httpClient;
        public EmployeeService(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }
 
   public async Task<Employee> GetEmployee(int id)
        {
//Error on receiving end 
            return await httpClient.GetJsonAsync<Employee>($"api/employees/{id}");
        }
}
 //Blazor Component Base class
  
  namespace EmployeeManagement.Web.Pages
    {
        public class EmployeeDetailsBase : ComponentBase
        {
            public Employee Employee { get; set; } = new Employee();
            [Inject]
            public IEmployeeService EmployeeService { get; set; }
            [Parameter]
            public string Id { get; set; }
            protected async override Task OnInitializedAsync()
            {
                Id = Id ?? "1";
                Employee = await EmployeeService.GetEmployee(int.Parse(Id));
            }
        }
    }

  // configuring in startup.cs 
   public void ConfigureServices(IServiceCollection services)
   {
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddHttpClient<IEmployeeService, EmployeeService>(client =>
    {
        client.BaseAddress = new Uri("https://localhost:44379/");
    });
   }
    Error: 
    HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).
    System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
    System.Net.Http.HttpClient.GetStringAsyncCore(Task<HttpResponseMessage> getTask)
    Microsoft.AspNetCore.Components.HttpClientJsonExtensions.GetJsonAsync<T>(HttpClient httpClient, string requestUri)
    XXXX.Services.EmployeeService.GetEmployee(int id) in EmployeeService.cs
    +
                    var item = await httpClient.GetJsonAsync<Employee>($"api/Employees/{id}");
    XXXX.Pages.EmployeeDetailsBase.OnInitializedAsync() in EmployeeDetailsBase.cs
    +
                    Employee = await EmployeeService.GetEmployee(int.Parse(Id));
    Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
    Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
    Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception)
    Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
    Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessAsynchronousWork()
    Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderRootComponentAsync(int componentId, ParameterView initialParameters)
    Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.CreateInitialRenderAsync(Type componentType, ParameterView initialParameters)
    Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.RenderComponentAsync(Type componentType, ParameterView initialParameters)
    Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext+<>c__11<TResult>+<<InvokeAsync>b__11_0>d.MoveNext()
    Microsoft.AspNetCore.Mvc.ViewFeatures.StaticComponentRenderer.PrerenderComponentAsync(ParameterView parameters, HttpContext httpContext, Type componentType)
    Microsoft.AspNetCore.Mvc.ViewFeatures.ComponentRenderer.PrerenderedServerComponentAsync(HttpContext context, ServerComponentInvocationSequence invocationId, Type type, ParameterView parametersCollection)
    Microsoft.AspNetCore.Mvc.ViewFeatures.ComponentRenderer.RenderComponentAsync(ViewContext viewContext, Type componentType, RenderMode renderMode, object parameters)
    Microsoft.AspNetCore.Mvc.TagHelpers.ComponentTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
    Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)
    Praxis.EGPSystemBlazor.Pages.Pages__Host.<ExecuteAsync>b__14_1() in _Host.cshtml
    +
            <component type="typeof(App)" render-mode="ServerPrerendered" />
    Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
    Praxis.EGPSystemBlazor.Pages.Pages__Host.ExecuteAsync() in _Host.cshtml
    +
        Layout = null;
    Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
    Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, bool invokeViewStarts)
    Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
    Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
    Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, string contentType, Nullable<int> statusCode)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
    Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
    Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
    Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

更新:感谢大家的回复。部门是强制性的。因此不存在无效的可能性。这是唯一有效的解决方案。我在Blazor项目中创建了另一个Viewmodel,它的所有字段都与ViewModelClass中的Employee和Initialized Department相同。然后我可以在UI中显示Employee.Department.DepartmentName。

public class EmployeeViewModel
 {
        public int EmployeeId { get; set; }
        [Required]
        [MinLength(2)]
        public string FirstName { get; set; }
        [Required]
        public string LastName { get; set; }
        public string Email { get; set; }
        public string ConfirmEmail { get; set; } 
        public DateTime DateOfBrith { get; set; }
        public Gender Gender { get; set; }
        public int DepartmentId { get; set; }
        public Department Department { get; set; }= new Department();
        public string PhotoPath { get; set; }
    }

web API项目和客户端项目是否也在web浏览器中加载?

如果没有,您可能需要从解决方案资源管理器转到解决方案的属性以启动多个项目。

导航到web API并在端口号后的地址栏中键入以下字符串可能是个好主意:

/api/员工/1

然后,如果浏览器显示Json,则一切正常。否则,您可以在web API中设置断点,并进一步调查错误发生的位置。

您可能想要使用Postman之类的东西来测试web API。

相关内容

  • 没有找到相关文章

最新更新