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");
}
}
Not a direct answer to my question, but I've got the workaround from https://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" }
);
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With