Handling 404 not found in MVC

The default 404 (not found) page for asp.net MVC and IIS is, well, less than ideal:

First attempt (aka the wrong way)

A lot of the advice out there says to create a specific error controller, and route from the web.config. To do this, add the following  


  

Then you can go on and create an error controller. Obviously you'll want to return something more meaningful that a bit of content.

public class ErrorController : Controller
{
	public ActionResult NotFound()
	{
		Response.StatusCode = 404;
		return Content("Nope, not here...");
	}
}

That works ok, displays the right content, and gets rid of the default page:

However, look at that Url?!?

http://localhost:62147/error/notfound?aspxerrorpath=/page-not-found

It's horrible! The other problem is it has actually redirected the user from the page they requested to your error url. That will then show up in your analytics and probably make your marketing department cry a little.

The better way

What we actually want to do is keep the user on the url they requested, but show our error page.

To do that, we need to ditch the custom errors section in the web config. Then replace it with the httpErrors section in system.webserver:


  
  

This will then hit our error controller, but preserve the url that the user is on. As we still have the code that sets the status code in the controller, it will return a 404 error code to the browser.

The last thing we need to do is log somewhere that an url that doesn't exists has been hit. Luckily, we can get the url from the request:

public class ErrorController : Controller
{
	public ActionResult NotFound()
	{
		//TODO: log this somewhere!
		var requestedUrl = Request.RawUrl;
		Response.StatusCode = 404;
		return View();
	}
}