I have an MVC 2 application that should always give a \'nice\' 404 page.
However currently I get a low level .Net one: \"Server Error in \'/sitename\' Applicatio
I finally found the answer to this, though it's still not ideal.
You can restrict the controller names that are allowed to match a route using a regex, so if we assume the default implementation of the controller factory we can figure out all the possible class names that are supported:
// build up a list of known controllers, so that we don't let users hit ones that don't exist
var allMvcControllers =
from t in typeof(Global).Assembly.GetTypes()
where t != null &&
t.IsPublic &&
!t.IsAbstract &&
t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
typeof(IController).IsAssignableFrom(t)
select t.Name.Substring(0, t.Name.Length - 10);
// create a route constraint that requires the controller to be one of the reflected class names
var controllerConstraint = new
{
controller = "(" + string.Join("|", allMvcControllers.ToArray()) + ")"
};
// default MVC route
routes.MapRoute(
"MVC",
"{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
controllerConstraint);
// fall back route for unmatched patterns or invalid controller names
routes.MapRoute(
"Catch All",
"{*url}",
new { controller = "System", action = "NotFound" });
This isn't ideal, it adds a hit on the application start and still feels far too complicated, but it does have the desired effect.