I have an internet-facing website that's built using MVC4 and I occasionally get error reports from bots or curious users who send requests for incomplete URLs.
For example:
public class ProductController : Controller { [HttpGet] public void View(int id) { // ... - A GET request to
/product/view/1is valid. - A GET request to
/product/viewis invalid as the argument is not specified.
Such invalid requests raise exceptions resembling:
System.ArgumentException: The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult View(Int32)' in 'Foo.ProductController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters at System.Web.Mvc.ActionDescriptor.ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary`2 parameters, MethodInfo methodInfo) at System.Web.Mvc.ReflectedActionDescriptor.<>c__DisplayClass1.<Execute>b__0(ParameterInfo parameterInfo) ... As the exception message states, I could make the id argument nullable and check within the action method, but I have many controllers with many actions.
I'd like to return a BadRequest/NotFound response to any request that fails to bind arguments to action parameters, and specify this in a single place in code to apply across all controllers.
How can this be done?
idwhich I don't want to do. Ifidis defined on the action and it's not provided, then the client made a mistake and I want to send them a 404. Also, I have various different controllers, each of which would require entries in my route config. The whole point here is that I don't want to make custom changes across my actions and config just in case some user/bot sends invalid requests -- they should be handled centrally and not raise exceptions that cause me to receive error emails which I just delete.