如何解决Blazor组件渲染时API 404未处理异常问题?
问题:Blazor调用API处理404错误的正确方式?
我在Blazor页面中调用API,当ApplicationID存在时可正常显示;当ApplicationID不存在时,Chrome控制台会抛出“Unhandled exception rendering component: Response status code does not indicate success: 404 (Not Found)”错误,且请求无法返回结果。
服务端代码
[ApiController] [Route("api/biographicdata/{applicationid}")] public class BiographicDataController : ControllerBase { private readonly IMediator _mediator; public BiographicDataController(IMediator mediator) { _mediator = mediator; } [HttpGet] public async Task<IActionResult> Get([FromRoute] long applicationid) { var response = await _mediator.Send(new GetBiographicData.Request { ApplicationID = applicationid }); if (string.IsNullOrEmpty(response.ErrorMessage)) { return Ok(response); } else { return NotFound(response); } } public async Task<BiographicData> Handle(Request request, CancellationToken cancellationToken) { var result = await _db.Applications.Include(a => a.Applicant).Where(a => a.ApplicationId == request.ApplicationID) .Select(x => new BiographicData { ApplicantId = x.ApplicantId, }).FirstOrDefaultAsync(cancellationToken); if (result == null) { result = new BiographicData() { ErrorMessage = $"The requested Application ID {request.ApplicationID} was not found.", }; } return result; } }
Blazor客户端代码
protected override async Task OnInitializedAsync() { AppState.UpdateApplicationID(this, appid); AppState.UpdateHelpURL(this, "Biographic_Information"); var client = await _factory.CreateClientAsync(); var result = await client.GetFromJsonAsync<BiographicData>($"api/biographicdata/{appid}"); if (string.IsNullOrEmpty(result.ErrorMessage)) { // 省略代码 } }
解决方案
有两种实用的处理方式,可根据业务需求选择:
方式一:统一返回200状态码,用错误信息标识资源不存在
这种方式避免404状态码触发客户端异常,始终返回成功状态,通过返回对象的ErrorMessage传递资源不存在的信息。
修改服务端Get方法:
[HttpGet] public async Task<IActionResult> Get([FromRoute] long applicationid) { var response = await _mediator.Send(new GetBiographicData.Request { ApplicationID = applicationid }); // 无论是否找到资源,都返回200状态码 return Ok(response); }
修改后Blazor端的GetFromJsonAsync能正常获取结果,继续执行后续的错误判断逻辑,不会抛出未处理异常。
方式二:保留404状态码,客户端主动捕获异常处理
如果要遵循REST规范(用HTTP状态码明确表示资源不存在),需要在Blazor端捕获HttpRequestException并处理404场景。
修改Blazor端代码:
protected override async Task OnInitializedAsync() { AppState.UpdateApplicationID(this, appid); AppState.UpdateHelpURL(this, "Biographic_Information"); var client = await _factory.CreateClientAsync(); BiographicData result = null; try { result = await client.GetFromJsonAsync<BiographicData>($"api/biographicdata/{appid}"); if (string.IsNullOrEmpty(result?.ErrorMessage)) { // 正常业务逻辑代码 } } catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { // 处理资源不存在的情况,比如初始化错误对象或提示用户 result = new BiographicData() { ErrorMessage = $"The requested Application ID {appid} was not found." }; } // 后续基于result的业务逻辑 }
服务端的NotFound返回逻辑可以保持不变,因为客户端已经能捕获并处理该异常。
补充说明
- 方式一更适合前端不想额外处理HTTP异常的场景,逻辑更统一;
- 方式二更符合RESTful API设计原则,通过状态码传递资源状态信息。
内容的提问来源于stack exchange,提问作者user22019322
相关产品推荐
相关产品推荐

