Friday, April 22, 2016

MVC 6 no exception thrown for undefined routes

Leave a Comment

I have a very basic asp.net MVC 6 app with basic routing, and I have a custom ErrorController to route errors to certain views.

I am expecting however that when the user types in an URL that does not exist, an exception is thrown (and I can handle it). However, no exception is thrown when I type in some random URL, I just get a blank page. I'm pretty sure this worked in similarly in MVC < 6.

The error handling itself works fine if I just throw an exception in a controller.

Startup.cs (partially)

public void Configure(IApplicationEnvironment appEnv, IApplicationBuilder app, IHostingEnvironment env) {     if (env.IsDevelopment())     {         app.UseBrowserLink();         app.UseDeveloperExceptionPage();     }     else     {         app.UseExceptionHandler(HandleException);     }     app.UseStaticFiles();     app.UseMvc(routes => MapRoutes(routes, appEnv)); }   private static void MapRoutes(IRouteBuilder routes, IApplicationEnvironment env) {     routes.MapRoute(        name: "default",        template: "{controller}/{action}/{id?}",        defaults: new { controller = "main", action = "index" });           }  private static void HandleException(IApplicationBuilder errorApp) {     #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously     errorApp.Run(async context => HandleErrorContext(context));     #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously }  private static void HandleErrorContext(HttpContext context) {     var error = context.Features.Get<IExceptionHandlerFeature>();     var exception = error.Error;     if (exception == null)     {         context.Response.Redirect("../error/external");     }     else if (exception is ExpirationException)     {         context.Response.Redirect("../error/expired");     }     else if (exception is HttpException)     {         var httpException = exception as HttpException;         int code = httpException.GetHttpCode();         context.Response.Redirect("../error/external?code=" + code);     }     else     {         context.Response.Redirect("../error/external");     } } 

2 Answers

Answers 1

Not a direct answer to my question, but I've got the workaround from http://stackoverflow.com/a/4833519/2713516 working. I'm still wondering why asp.net is not throwing a 404 though.

           routes.MapRoute(                 "PageNotFound",                 "{*catchall}",                 new { controller = "Home", action = "PageNotFound" }                 ); 

Answers 2

You can show user-friendly error pages by adding the StatusCodePages middleware to the pipeine. In Startup.cs

public void Configure(IApplicationEnvironment appEnv, IApplicationBuilder app, IHostingEnvironment env) {     if (env.IsDevelopment())     {         app.UseBrowserLink();         app.UseDeveloperExceptionPage();     }     else     {         app.UseExceptionHandler("/error/500");         app.UseStatusCodePagesWithReExecute("/error/{0}");     }     app.UseStaticFiles();     app.UseMvc(routes => MapRoutes(routes, appEnv)); } 

The response body should be generated by re-executing the path /error/{0}.

[Route("[controller]")] public class ErrorController : Controller {                  [HttpGet("{statusCode}")]      public IActionResult Error(int statusCode)      {                 //switch (statusCode)            //{              //    return different views...            //}             Response.StatusCode = statusCode;            return View("Error", statusCode);      } } 

Thats how you can show a 404 error page or any other error page.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment