【问题标题】:How to Override 415 response in ASP.Net Core2.2如何在 ASP.Net Core2.2 中覆盖 415 响应
【发布时间】:2019-05-06 09:10:07
【问题描述】:

在 .net core 2.2 中,有一个默认的 json,状态码为 415,比如

{
   "type":"https://tools.ietf.org/html/rfc7231#section-6.5.13",
   "title":"Unsupported Media Type",
   "status":415,
   "traceId":"8000003e-0001-f500-b63f-84710c7967bb"
}

我不知道这个 JSON 是怎么来的。 我按照下面的example重写json

但我得到了不同的结果,它在原始 json 中添加了一个部分。这是我的 Wireshark 结果

HTTP/1.1 415 不支持的媒体类型传输编码:分块

Content-Type:应用程序/问题+json; charset=utf-8 服务器:

Microsoft-IIS/10.0 X-Powered-By:ASP.NET 日期:星期一,2019 年 5 月 6 日 09:03:56 GMT

{
   "type":"https://tools.ietf.org/html/rfc7231#section-6.5.13",
   "title":"Unsupported Media Type",
   "status":415,
   "traceId":"8000002c-0002-fb00-b63f-84710c7967bb"
}
{
   "data":"this is custom message"
}

过滤器

public class MediaTypeResouceFilter : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        if (context.HttpContext.Response.StatusCode == 415)
        {
            var jsonString = JsonConvert.SerializeObject(new { data = "this is custom message" });
            byte[] data = Encoding.UTF8.GetBytes(jsonString);
            context.HttpContext.Response.Body.WriteAsync(data, 0, data.Length);
        }
    }
}

【问题讨论】:

  • 实际上,它所做的是使响应不是 JSON。 JSON 不支持对象像这样相互跟随。我不是 ASP.NET Core 专家,但也许您同时启用了现有过滤器和新过滤器,并且它们都添加了输出?
  • @LasseVågsætherKarlsen 这真的不是 JSON,但在 wireshark 结果中它的内容类型是 application/problem+json
  • 我仍然猜测现有过滤器和您的过滤器都按旧+新的顺序添加各自的输出。现在,一个更好的问题是问你真正想要发生什么?您是否要将您的属性添加到现有响应中?您是否想删除旧的回复并只回复{ "data": "this is custom message" }我问,因为您的问题似乎暗示您当前的回复是错误的,但您没有说明您认为正确的内容。这使得任何人都很难提出建议。
  • @LasseVågsætherKarlsen 我想删除旧的回复,只回复 { "data": "this is custom message" } 。我确定我的 webapi 中只有一个过滤器
  • 如果在编写自己的之前没有办法(或太迟)清除输出,那么您将需要禁用/重新实现现有过滤器以确保它不会先输出自己的消息.

标签: c# asp.net-core


【解决方案1】:

我不知道这个 JSON 是怎么来的。

[ApiController] 属性应用于控制器时,它会启用Problem details for error status codes,最终会在该控制器的MVC 过滤器管道中添加一个内置操作过滤器。此操作过滤器适用于所有状态代码 >= 400 并生成您描述的 JSON 响应。

它在原始 json 中添加了一个部分

当您的 MediaTypeResouceFilter.OnResourceExecuted 代码运行时,我上面提到的操作过滤器已经将 JSON 写入正文。您将一个额外的 JSON 格式的字符串写入正文,它只是被附加并将响应破坏为无效的 JSON。

如果您想禁止此问题详细信息 JSON 被写入响应,您可以将以下内容添加到您的 Startup.ConfigureServices 代码以禁止该功能:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
    .ConfigureApiBehaviorOptions(options =>
    {
        options.SuppressMapClientErrors = true;
    };

【讨论】:

    【解决方案2】:

    看起来您只是附加到正文,并且在执行过滤器之前写入正文的任何​​内容都保留在正文中。

    如果您take a look at the documentation 了解如何实现 IResource 过滤器,您可以使用这行代码实现您的目标,但在 OnResourceExecuting 内部代替:

    context.Result = new ContentResult()
    {
        Content = jsonString
    };
    

    文档指出:

    您可以通过在提供给过滤器方法的上下文参数上设置 Result 属性,在任何时候短路过滤器管道。

    如果您将该代码放在 OnResourceExecuting 中。

    【讨论】:

    • 我试过这个方法。但是响应体不会改变。stackoverflow.com/questions/53166761/…">关注有同样的问题
    • @Z.Chen 您是否尝试过将其放入 OnResourceExecuting 中?文档说它需要去那里。
    • 如果我把它放到 OnResourceExecuting 中,我无法识别响应状态码。它总是 200。
    猜你喜欢
    • 1970-01-01
    • 2017-01-30
    • 2022-07-10
    • 1970-01-01
    • 2018-04-02
    • 2011-09-13
    • 2015-08-30
    • 2013-07-25
    • 2012-03-30
    相关资源
    最近更新 更多