简体   繁体   中英

Redirect in Asp.Net Core middleware does not render target page

I added a middleware item (called CDASMiddleware) in Startup.cs that identifies 4xx http errors and does a redirection to a error handler that logs the error to the database and displays a custom error page.

As an example, lets assume I wish to track 404 errors. The Invoke method of the middleware handles that error with the following code.

public async Task Invoke(HttpContext httpContext)
{
     await _next(httpContext); 
     if (httpContext.Response.StatusCode == 404)
     {
         var message = $@"404 error. URL: {httpContext.Request.Path.Value}   was not found.";
         Error e = new Error() { StatusCode = "404", Message = message };
         var obj = JsonConvert.SerializeObject(e);
         httpContext.Session.SetString("HttpError", obj);
         var url = httpContext.Request.PathBase + "/Error/HttpError";
         httpContext.Response.Redirect(url, true);
    }
}

And, indeed, when this code is called, the corresponding controller method is called which successfully stores the error in the database and then returns the associated view.

 public IActionResult HttpError() 
     {
         var session = this.HttpContext.Session;
         Error e = JsonConvert.DeserializeObject<Error>(session.GetString("HttpError"));
         var el = GetErrorLogFromError(e); //create error log entry for db
         _dataContext.ErrorLogDataSet.Upsert(el);   
         return View("~/Views/Shared/Error.cshtml", e);
     }

Upon doing a F12 debug in the browser, as expected, I see a 302 (have tried 301 as well) associated with the redirect and a subsequent 200 response with the correct html view in the http body. So the browser gets the correct view. But it is not rendered and the browser url does not change to reflect the redirection.

Oh, and the Configure method in Startup.cs is

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ICDASDataContext dataContext)
        {
            app.UseSession();
            app.UseCDASMiddleware();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage(); //show detailed error page to developer
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/CDASUnhandledException");  //log to the database and show a custom error page to user for unhandled exceptions
                Func<string, LogLevel, bool> f = ((s, logLevel) => logLevel >= LogLevel.Error); //log handled errors
                loggerFactory.AddProvider(new CDASLoggerProvider(f, dataContext));
            }
            app.UseStaticFiles();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "AreaRoute",
                    template: "{area:exists}/{controller}/{action}",
                    defaults: new { controller = "Home", action = "Index" });

                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");


            });
        }

Any ideas?

If the initiating call is a javascript ajax call, as was the case with in this head scratcher, the redirection in the middleware causes the server to create the redirected page and return it to the fail callback of the ajax call. In that callback, a document.write(data.responseText) can be used to render the error page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM