I have a default route with an optional id
parameter that matches a lot of controller methods, which is desired.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
);
Most controllers define the id param as an int rather than a nullable int. For example:
public ActionResult Detail(int id)
{
var model = GetModel(id);
return View(model);
}
The problem is that, in this large web app, occasionally some errant code will direct the user to a path without the id. For example, /ControllerName/Detail
. The default route is invoked, but an exception is logged because of the missing parameter:
System.ArgumentException: The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Detail(Int32)'
There will be an effort to find out why such a request is happening in the first place, but I'd also like to avoid logging the exception, and show a 404 page instead of a 500 page. The questions I've seen provide solutions for an unknown controller or action, but not a param that the default route defines as optional, but the action method defines as required.
I've tried adding my "catchall" route before the default, with id given a value of 0:
routes.MapRoute(
name: "CatchAll",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index", id = 0 },
);
This prevents the exception, but I want to show a 404 error page. Is there any way to do this in the route config, instead of changing every action method to expect an int? id
and then redirecting to the 404 page if !id.HasValue
?