Custom error pages for HTTP status codes in ASP.NET MVC

I am a recent graduate at the beginning of my software development career. I enjoy documenting my learnings through my blogs
Background
I encountered a problem with my custom error pages when completing a college project. I had 2 HTTP errors which I wanted to use a custom error page for, “404 - Not Found” and “401 - Unauthorized”. To create these custom errors, I first created an “Error” controller and then made an ActionResult method for each error, within this controller and created views for the errors from these methods. The 404 error worked, whereby if an ID was not used in the URL or did not exist, a custom 404 error page was displayed to the user. However, the 401 error I intended to use when a user tried to access certain links/pages when they were not logged in was throwing a runtime error instead of my custom error page.
Creating a custom Error page in MVC
Creating a custom error page is relatively simple. Do note that there is already an Error.cshtml view available in the /Shared/Views folder with the default ASP.NET MVC template.
Create a Controller for the custom error(s) you want to use, I named my controller
ErrorController.Inside this controller you will need a method that returns
ActionResultfor each error.public class ErrorController : Controller { // GET: Error public ActionResult NotFound() { Response.StatusCode = 404; return View(); } // GET: Error public ActionResult BadRequest() { Response.StatusCode = 400; return View(); } }The next step is creating the relevant views for each error. You can do this by right-clicking on the method name, ie. NotFound and selecting the
“Add View”option.Update the information in this view to whatever you want your error page to tell the user.
Next, open the
Web.configfile for your MVC application, make sure to choose the correct file as there is aWeb.configfile in the Views folder (you do not want this file).In the
Web.configfile find the<system.web>attribute. Within this attribute add a<customErrors>attribute withmode=”On”. See below for an example…<customErrors mode="On"> <error statusCode="400" redirect="/Error/BadRequest"/> <error statusCode="404" redirect="/Error/NotFound"/> </customErrors>Open the
Global.asaxfile for your MVC application and in this add theHandleErrorAttibute. The last line in the example is what you will need to add, your code should look something like this.protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); GlobalFilters.Filters.Add(new HandleErrorAttribute()); }Lastly, update your exceptions in the relevant controllers. Your exception will look similar to this depending on your error code.
throw new HttpException(404, "Not Found");
Solution
Because my 401 error code would not work for my intended purpose I instead used the [Authorize] attribute on certain actions within my relevant controller, see Simple Authorization for more information on the [Authorize] attribute. For example, I used the [Authorize] attribute to redirect a link to the login page if a user was not logged in. The redirect here is simply a side-effect of the user not being signed in when trying to access a route (Controller action) that is decorated with an [Authorize] attribute. In doing this I did not have to redirect to an error page when a User was not logged in and the [Authorize] attribute was used in its simplest form.
[Authorize]
public ActionResult AddToFavourites(int id)
{
}
Conclusion
In conclusion, my error for code 401 not working was a good thing. This helped me search for alternative solutions to a problem, which led me to the [Authorize] attribute, which turned out to be a better fit for what I wanted.




