如何在Blazor WASM中获取Status204NoContent状态码对应的自定义返回消息
解决ASP.NET Core返回204 NoContent时传递错误消息的问题
首先得明确一个HTTP规范细节:204 No Content状态码的响应体必须是空的,所以你当前在控制器里用StatusCode(StatusCodes.Status204NoContent, "Cannot Do It!")的方式,虽然写了消息,但这个消息不会被包含在响应里(ASP.NET Core会自动忽略响应体内容),这也是你在Blazor里拿不到它的核心原因。
下面给你两种可行的解决方案,按推荐程度排序:
方案一:使用语义匹配的错误状态码(推荐)
既然你的场景是操作失败(无法完成日历条目更新),用204其实不符合HTTP语义(204表示请求成功但无内容返回)。更合适的做法是用400 Bad Request或者422 Unprocessable Entity这类错误状态码,把消息放在响应体里,这是最规范且可靠的方式。
控制器代码修改:
[HttpPost] public async Task<ActionResult> UpdateCalendarEntry(CalendarEntry model) { try { model.LabelColor = "blue"; var result = await repo.AddCalendarEntry(model); if(result == null) { // 用BadRequest返回错误消息,响应体将包含该内容 return BadRequest("Cannot Do It!"); // 或者如果你想更明确表示请求格式正确但业务上无法处理,用422: // return StatusCode(StatusCodes.Status422UnprocessableEntity, "Cannot Do It!"); } return apiResult.Send200(result); } catch (Exception ex) { return apiResult.Send400(ex.Message); } }
Blazor服务代码修改:
if(response.StatusCode == HttpStatusCode.BadRequest) { // 直接读取响应体里的错误消息 var errorMessage = await response.Content.ReadAsStringAsync(); await helperService.InvokeAlert("Bad Request", errorMessage, true); } // 如果用了422状态码,补充对应的判断: // if(response.StatusCode == (HttpStatusCode)422) // { // var errorMessage = await response.Content.ReadAsStringAsync(); // await helperService.InvokeAlert("Operation Failed", errorMessage, true); // }
方案二:给204设置ReasonPhrase(不推荐,仅当必须用204时)
如果你因为某些业务限制一定要用204状态码,可以通过设置Response的ReasonPhrase来传递消息,但要注意:不是所有HTTP客户端或代理都会保留ReasonPhrase,所以这不是最可靠的方式。
控制器代码修改:
[HttpPost] public async Task<ActionResult> UpdateCalendarEntry(CalendarEntry model) { try { model.LabelColor = "blue"; var result = await repo.AddCalendarEntry(model); if(result == null) { // 获取Response特性,手动设置ReasonPhrase var responseFeature = HttpContext.Features.Get<IHttpResponseFeature>(); responseFeature.ReasonPhrase = "Cannot Do It!"; // 返回NoContent,确保响应体为空符合HTTP规范 return NoContent(); } return apiResult.Send200(result); } catch (Exception ex) { return apiResult.Send400(ex.Message); } }
Blazor服务代码修改:
if(response.StatusCode == HttpStatusCode.NoContent) { // 直接读取响应头里的ReasonPhrase var errorMessage = response.ReasonPhrase; await helperService.InvokeAlert("Operation Failed", errorMessage ?? "No content returned", true); }
为什么你之前的方式无效?
你原来在控制器里传的第二个参数是响应体内容,但204的HTTP规范强制要求响应体必须为空,所以ASP.NET Core会自动丢弃这个内容,导致你在Blazor里调用ReadAsStringAsync()拿不到任何东西。而ReasonPhrase是HTTP响应头的一部分,和响应体无关,所以需要手动设置它才能被客户端获取。
内容的提问来源于stack exchange,提问作者Ibanez1408
相关产品推荐
相关产品推荐

