ASP.NET MVC 6 handling errors based on HTTP status code

后端 未结 3 1809
夕颜
夕颜 2021-02-20 05:12

I want to display different error messages for each status code e.g:

  • 400 Bad Request
  • 403 Forbidden
  • 500 Internal Server Error
  • 404 Not Fou
3条回答
  •  野性不改
    2021-02-20 05:46

    How can I achieve this in the new ASP.NET MVC 6 applications? Can I do this using the built in UseErrorHandler method?

    Quick answer: Not in an elegant fashion.

    Explanation/Alternative: To start lets first look at what the UseErrorHandler method is actually doing: https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6e7259de81f83a04d1654170137/src/Microsoft.AspNet.Diagnostics/ErrorHandlerExtensions.cs#L25 which adds the following middleware: https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6e7259de81f83a04d1654170137/src/Microsoft.AspNet.Diagnostics/ErrorHandlerMiddleware.cs Note lines 29-78 (the invoke method)

    The invoke method is executed whenever a request comes in (controlled by the location of your application.UseErrorHandler("...") in your Startup.cs). So the UseErrorHandler is a glorified way of adding a custom middleware: middleware = component that can act on an http request.

    Now with that background, if we wanted to add our own error middleware that differentiated requests. We could do this by adding a similar middleware that's like the default ErrorHandlerMiddleware by modifying these lines: https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6e7259de81f83a04d1654170137/src/Microsoft.AspNet.Diagnostics/ErrorHandlerMiddleware.cs#L48-L51 With that approach we could control the redirect path based on the status code.

    In MVC 5 we have had to use the system.web customerrors section for ASP.NET and the system.webServer httpErrors section in the web.config file but it was difficult to work with an unwieldy, with lots of very strange behaviour. Does MVC 6 make this a lot simpler?

    Answer: It sure does :). Just like the above answer the fix lies in adding middleware. There's a shortcut to adding simple middleware via the IApplicationBuilder in your Startup.cs; at the end of your Configure method you can add the following:

    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("Could not handle the request.");
    
        // Nothing else will run after this middleware.
    });
    

    This will work because it means that you reached the end of your http pipeline without the request being handled (since it's at the end of your Configure method in Startup.cs). If you want to add this middleware (in the quick fashion) with the option to execute middleware after you, here's how:

    app.Use(async (context, next) =>
    {
        await context.Response.WriteAsync("Could not handle the request.");
    
        // This ensures that any other middelware added after you runs.
        await next();
    });
    

    Hope this helps!

提交回复
热议问题