You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 19:02:51