Reputation: 57
I have an ApiController - for example 'Home' controller, with action 'Test' which accepts two parameters - test1 and test2, both with default values
[System.Web.Http.HttpGet]
public ActionResult Test(int test1 = 3, int test2 = 5)
{
var a = 0;
return null;
}
Now when I call Home/Test?test1=1, everything is OK.
But when I call Home/Test?test1=1&, the server throws exception
The parameters dictionary contains a null entry for parameter 'test2' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Test(Int32, Int32)' in 'TestAPI.Controllers.ValuesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
My route configuration is currently like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
This also happens on a brand new WebApi project so it is not something from my configuration.
The big problem is that this ampersand comes from a client project and I cannot change it there, although I am aware that this is a bad request.
The strangest thing is that if Home controller is inheriting Controller instead of ApiController - everything is fine.
Edit 1
I forgot to mention that if I make the parameters nullable (i.e. int?) then the error dissapears but test2 has value of null instead of 5 when calling the bad URL, so this is not an option for me.
Upvotes: 3
Views: 584
Reputation: 2574
You can use a custom DelegatingHandler
and remove trailing '&':
public class SanitizeHandler : System.Net.Http.DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.RequestUri.ToString().EndsWith("&"))
request.RequestUri = new Uri(request.RequestUri.ToString().TrimEnd('&'));
return base.SendAsync(request, cancellationToken);
}
}
Register the new Handler in Application_Start
:
GlobalConfiguration.Configuration.MessageHandlers.Add(new SanitizeHandler());
Or add it to your HttpConfiguration
(then it is only called with Webapi calls):
public static void Register(HttpConfiguration config)
{
...
config.MessageHandlers.Add(new SanitizeHandler());
...
}
Upvotes: 2