【问题标题】:Custom 404 response model自定义 404 响应模型
【发布时间】:2022-03-04 06:49:41
【问题描述】:

我想为我们 API 上的所有 404 提供自定义响应。例如:

{
  "message": "The requested resource does not exist. Please visit our documentation.."
}

我相信以下结果过滤器适用于 MVC 管道中的所有情况:

public class NotFoundResultFilter : ResultFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        var result = context.Result as NotFoundResult;

        if (result != null)
        {
            context.Result = new HttpNotFoundResult(); // My custom 404 result object
        }
    }
}

但是,当请求的 URL 与操作路由不匹配时,上述过滤器不会被命中。 我怎样才能最好地拦截这些 404 响应?这需要中间件吗?

【问题讨论】:

    标签: asp.net-core asp.net-core-mvc asp.net-core-1.0


    【解决方案1】:

    是的,您需要使用中间件,因为过滤器仅适用于 MVC。

    1. 您可以像往常一样编写自己的中间件

      app.Use(async (context, next) =>
      {
          await next();
          if (context.Response.StatusCode == 404)
          {
              context.Response.ContentType = "application/json";
      
              await context.Response.WriteAsync(JsonConvert.SerializeObject("your text"), Encoding.UTF8);
          }
      });
      
    2. 或者使用内置的中间件StatusCodePagesMiddleware,但是由于您只想处理一个状态,这是一个额外的功能。此中间件可用于处理介于 400 和 600 之间的响应状态码。您可以配置 StatusCodePagesMiddleware,在 Configure 方法中添加以下行之一(示例来自 StatusCodePages Sample):

      app.UseStatusCodePages(); // There is a default response but any of the following can be used to change the behavior.
      
      // app.UseStatusCodePages(context => context.HttpContext.Response.SendAsync("Handler, status code: " + context.HttpContext.Response.StatusCode, "text/plain"));
      // app.UseStatusCodePages("text/plain", "Response, status code: {0}");
      // app.UseStatusCodePagesWithRedirects("~/errors/{0}"); // PathBase relative
      // app.UseStatusCodePagesWithRedirects("/base/errors/{0}"); // Absolute
      // app.UseStatusCodePages(builder => builder.UseWelcomePage());
      // app.UseStatusCodePagesWithReExecute("/errors/{0}");
      

    【讨论】:

    • 谢谢!我不相信中间件可以那样工作,因为 HttpContext 没有 Result 属性。我相信 UseStatusCodePages() 可能不适合,因为我想返回 JSON。
    • 非常适合 404。使用 JwtBearerAuthentication 中间件时,我似乎无法让它与 401 或 403 一起使用,但我会在另一个问题中提出这个问题。
    • 我在这里问过这个问题stackoverflow.com/questions/38281116/…
    【解决方案2】:

    试试这个:

    app.Use( async ( context, next ) =>
    {
        await next();
    
        if ( context.Response is { StatusCode: 404, Body: { Length: 0 }, HasStarted: false } )
        {
            context.Response.ContentType = "application/problem+json; charset=utf-8";
            string jsonString = JsonConvert.SerializeObject(errorDTO);
            await context.Response.WriteAsync( jsonString, Encoding.UTF8 );
        }
    } );
    

    【讨论】:

      猜你喜欢
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      • 2022-10-02
      • 2021-11-15
      • 2015-09-04
      • 1970-01-01
      • 2017-02-20
      • 2020-05-08
      相关资源
      最近更新 更多