https://www.youtube.com/watch?v=UBNRcaw1bDk&list=PL6n9fhu94yhVowClAs8-6nYnfsOTma14P&index=23
Hi I'm trying to implement project as mentioned in above link. I'm trying get data from ASP.NET WebAPI project and consume in Blazor project. I have no issue retrieving data from single table. But when I try to retrieve data from Secondary table . I'm getting error below:
"HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error)."
I tried casting the result (in API project)explicitly to 'Employee' class before sending. Didn't work. Debug on API clearly shows returning Employee with Department information but on Blazor project while receiving getting error. Thanks in advance!!
UPDATE:
Thank you all for offering help. Here is the original code.
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)
Update : Thanks all for response. Department is mandatory.So there is no chance of null. This is the only solution that worked. I have created another Viewmodel in Blazor project that has all fields same as Employee and Initialized Department inside ViewModelClass. Then I was able to show Employee.Department.DepartmentName in UI.
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; }
}