https://www.youtube.com/watch?v=UBNRcaw1bDk&list=PL6n9fhu94yhVowClAs8-6nYnfsOTma14P&index=23
嗨,我正在尝试实施上述链接中提到的项目。我正在尝试从 ASP.NET WebAPI 项目中获取数据并在 Blazor 项目中使用。我从单个表中检索数据没有问题。但是当我尝试从 Secondary table 检索数据时。我在下面收到错误:
“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; }
}