简体   繁体   中英

ASP.Net Core MVC UseExceptionHandler results in blank page

Building an ASP.Net Core (V2) MVC Site.

We are using API Versions for this.

The site has controllers delivering MVC Razor Views as well as API-style Json responses.

I am trying to use the UseExceptionHandler() method, as shown below.

When i hit an exception in one of my actions, the action gets executed again and then a blank page shown. The browser console is free from any errors too. Finally, my error action is never hit.

I have a custom exception filter in place for the API controllers, also shown below. I have commented this out, figuring it was interfering. This didn't resolve any issue.

Where am I going wrong? And how can i have my custom error page hit when there is an exception.

Exception Handler Method - This results in "/v1.0/home/error"

app.UseExceptionHandler($"/v{appSettings.Value.APIVersion}/home/error");

I have also tried, after reading that this is supposed to be the path to a view

app.UseExceptionHandler("/error");

and

app.UseExceptionHandler("/views/home/error");

The Error Action

 [HttpGet("error")]
 public IActionResult Error()
 {
      var exception = HttpContext.Features.Get<IExceptionHandlerFeature>();
      ViewData["statusCode"] = HttpContext.Response.StatusCode;
      ViewData["message"] = exception.Error.Message;
      return View();
 }

The Exception Filter (currently commented out in the startup.cs)

public override void OnException(ExceptionContext context)
 {
       if (context.HttpContext.Request.Path.Value.Contains("/api"))
       {
             // Set the response
             context.ModelState.GroupErrorsIntoKey("ErrorArray");
             context.ModelState.AddModelError("ErrorArray", context.Exception.Message);
             context.Result = new BadRequestObjectResult(context.ModelState);
         }
 }

I have a similar mixed Razor/API design and ran into the same issue. Apparently, it is happening due to a change in the action resolution process in 2.0. This issue " Problems using UseExceptionHandler() " describes it in great detail and offers workarounds.

To quote the explanation offered by Microsoft/aspnet-api-versioning developer (from the link above):

"This issue is happening due to a change in the action resolution process in 2.0, which fixed a bug that affected some, but not all, in 1.0. The ASP.NET Core design expects that the pipeline stops on the first action match. If there are no actions, the error path is taken, which is usually 404. This is combined by the fact that the platform might call the action selector multiple times. The consequence of this behavior is that API versioning cannot make its decision until all possible routes have been considered. The only way to know that is to have a catch all route that is executed at the end. Unfortunately, this causes some other end of route behaviors to behave unexpectedly as you are seeing. As you can imagine, it would be highly inefficient to re-evaluate the entire route tree on every request. To optimize things, API versioning tracks whether the versioning policy has been evaluated at least once for a given route. Once it has, it can make the final decision much earlier in the pipeline. This is what is resulting the behavior where you first see things not do what you expected and then subsequent calls are ok."

The workaround is to configure UseExceptionHandler() a bit differently. Here is what worked for me:

app.UseExceptionHandler(new ExceptionHandlerOptions
{
  ExceptionHandler = async context =>
  {
     var exception = context.Features.Get<IExceptionHandlerFeature>().Error;

     if (!context.Request.Path.StartsWithSegments(new PathString("/api"), StringComparison.OrdinalIgnoreCase))
     {
        context.Response.Redirect("Error");
     }
     else
     {
        context.Response.ContentType = "application/json";
        var response = new
        {
            Error = exception.Message
        };
        await context.Response.WriteAsync(JsonConvert.SerializeObject(response));
     }
   }
});

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