How to use UseExceptionHandler in the mvc startup without redirecting the user?

两盒软妹~` 提交于 2020-12-15 03:42:56

问题


I have a ASP.NET Core 2.1 MVC application, and I'm trying to return a separate html view when an exception occurs. The reason for this is that if there are errors, we don't want google to register the redirects to the error page for our SEO (I've omitted development settings to clear things up).

Our startup contained this:

app.UseExceptionHandler("/Error/500"); // this caused a redirect because some of our middleware.
app.UseStatusCodePagesWithReExecute("/error/{0}"); 

But we want to prevent a redirect, so we need to change the UseExceptionHandler. I've tried to use the answer from this question like below:

app.UseExceptionHandler(
            options =>
            {
                options.Run(
                    async context =>
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                        context.Response.ContentType = "text/html";
                        await context.Response.WriteAsync("sumtin wrong").ConfigureAwait(false);

                    });
            });

But this gives a very ugly page without any styling. Another solution we've tried to use is creating an error handling middle ware, but there we run into the same problem there where we can't add a view.

How can I return a styled view in case of an exception, without redirecting the user?

EDIT: the UseExceptionHandler doesn't cause a redirect, it was caused by a bug in some of our middleware.


回答1:


How can I return a styled view in case of an exception, without redirecting the user?

You're almost there. You could rewrite(instead of redirect) the path, and then serve a HTML according to current path.

Let's say you have a well-styled sth-wrong.html page in your wwwroot/ folder. Change the code as below:

app.UseExceptionHandler(appBuilder=>
{
    // override the current Path
    appBuilder.Use(async (ctx, next)=>{
        ctx.Request.Path = "/sth-wrong.html";
        await next();
    });
    // let the staticFiles middleware to serve the sth-wrong.html
    appBuilder.UseStaticFiles();
});

[Edit] :

Is there anyway where I can make use of my main page layout?

Yes. But because a page layout is a View Feature that belongs to MVC, you can enable another MVC branch here

  1. First create a Controllers/ErrorController.cs file :

    public class ErrorController: Controller
    {
        public IActionResult Index() => View();
    }
    

    and a related Views/Error/Index.cshtml file:

    Ouch....Something bad happens........
    
  2. Add a MVC branch in middleware pipeline:

    app.UseExceptionHandler(appBuilder=>
    {
        appBuilder.Use(async (ctx, next)=>{
            ctx.Request.Path = "/Error/Index";
            await next();
        });
        appBuilder.UseMvc(routes =>{
            routes.MapRoute(
                name: "sth-wrong",
                template: "{controller=Error}/{action=Index}");
        });
    });
    

Demo:



来源:https://stackoverflow.com/questions/59765573/how-to-use-useexceptionhandler-in-the-mvc-startup-without-redirecting-the-user

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!