The following solution satisfies most of your requirements, with the exception of:
- But this does not provide access to anything that the user must be authenticated to access . It is very dependent on your architecture of your application, however this method does not add any risk of this event.
- This works the same in IIS7, IIS Express, and Casini does not use Casini, so it cannot be guaranteed.
- This works in MVC5, but will continue to work in MVC6, MVC7, etc. Didn't try this in MVC6
- This allows us to process any subcodes, such as 404.3, which we need to process separately . It depends on what you mean by this - you can return Response.SubStatusCode to the client in the results of your actions. If you want to process it in the application, provided that it is in the created exception object, you can access it.
Create an ErrorController - this allows you to customize error pages and end-user status codes .:
[AllowAnonymous] public class ErrorController : Controller { public ActionResult PageNotFound() { Response.StatusCode = 404; return View(); } public ActionResult ServerError() { Response.StatusCode = 500; return View(); } public ActionResult UnauthorisedRequest() { Response.StatusCode = 403; return View(); }
Add a route to catch all the URLs to the end of your route configuration - this captures all 404 that are not yet caught by matching existing routes:
routes.MapRoute("CatchAllUrls", "{*url}", new { controller = "Error", action = "CatchAllUrls" });
In your global.asax:
protected void Application_Error(object sender, EventArgs e) { Exception exception = Server.GetLastError(); //Error logging omitted HttpException httpException = exception as HttpException; RouteData routeData = new RouteData(); IController errorController = new Controllers.ErrorController(); routeData.Values.Add("controller", "Error"); routeData.Values.Add("area", ""); routeData.Values.Add("ex", exception); if (httpException != null) { //this is a basic exampe of how you can choose to handle your errors based on http status codes. switch (httpException.GetHttpCode()) { case 404: Response.Clear(); // page not found routeData.Values.Add("action", "PageNotFound"); Server.ClearError(); // Call the controller with the route errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); break; case 500: // server error routeData.Values.Add("action", "ServerError"); Server.ClearError(); // Call the controller with the route errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); break; case 403: // server error routeData.Values.Add("action", "UnauthorisedRequest"); Server.ClearError(); // Call the controller with the route errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); break; //add cases for other http errors you want to handle, otherwise HTTP500 will be returned as the default. default: // server error routeData.Values.Add("action", "ServerError"); Server.ClearError(); // Call the controller with the route errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); break; } } //All other exceptions should result in a 500 error as they are issues with unhandled exceptions in the code else { routeData.Values.Add("action", "ServerError"); Server.ClearError(); // Call the controller with the route errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); } }
In summary:
- Custom pages for standard HTTP errors. You have full control over the page returned to the user.
- The same as on the standard pages of my site . You can use your look if you want custom pages
- Without the need to completely redo everything I have in my Shared / _Layout.cspx as above
- This works whether the user is authenticated or not. This partly applies to your architecture, but there is nothing in the proposed method that could interfere with user authentication
- This should correctly return the URL requested using the appropriate HTTP error code, and not the administration to another page that returns HTTP 200 There is no redirect to the error page to maintain the correct http status code
- This redirects everything that is not a valid route to page 404, whether it is a missing action, a missing controller, or a missing route.
- This does not involve adding separate code to each page.
source share