自定义 404 响应模型

Custom 404 response model

我想为 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 响应?这需要中间件吗?

是的,您需要使用中间件,因为过滤器仅适用于 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, but as you want to handle only one status, this is an extra functionality. This middleware can be used to handle the response status code is between 400 and 600 .You can configure the StatusCodePagesMiddleware adding one of the following line to the Configure method (example from 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}");
    

试试这个:

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 );
    }
} );