Question

I'm sending multiple requests to the same action method in a controller all these requests have some common querystring attributes and some specific to that request.

request1 : http://localhost/home/test?a=a1&b=b1&c=c1&d=d1....around 25 parameters

request2 : http://localhost/home/test?a=a1&b=b1&j=j1&k=k1...around 20 parameters

similarly request 3 , request4,etc...

My action method in mvc in homecontroller is as below..

public string test(string a, string b, string c, string d, ...around 50 parameters)

This is working perfectly..

But when I take this code and move it to web api, it no longer works..

Moreover, if I try with just two parameters, it works and I can get the two parameters.. public string test(string a, string b)

I have no control on the requests that I receive in my application as it is coming from a 3rd party host application, so the method name and parameters can not change ...

The route configured in mvc in route.config is standard..

routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

I have configured a separate route for webapi in webapiconfig on similar lines..

config.Routes.MapHttpRoute(
             name: "ActionApi",
             routeTemplate: "api/{controller}/{action}/{id}",
             defaults: new { id = RouteParameter.Optional }
            ); 

Any ideas how to solve this..

Thanks Arnab

Was it helpful?

Solution

The reason is that Web API does action overloading and all these parameters are required, if they are not provided you are ending up with 404. The simple answer to your question is to make them optional by giving them a default value, so your signature will look like this:

public IHttpActionResult Get(string a = null, string b = null, ...)

However this code seems very elaborate for what you are doing, it's probably also not the most efficient and you end up with a lot of if statements.

Consider alternatively just parsing the query string yourself and get a more convenient to use data set.

public class ValuesController : ApiController
{
    public IHttpActionResult Get()
    {
        var collection = Request.RequestUri.ParseQueryString();
        foreach (var key in collection.Keys)
        {
            var value = collection[(string)key];

            // do something with key & value
        }

        return Ok();
    }
}

and as another option is to build a model including all the parameters, something like:

public class Settings
{
    public string A { get; set; }
    public string B { get; set; }
    ...
}

and bind to the model using the FromUri:

public IHttpActionResult Get([FromUri]Settings settings)
{
    ...
}

Here is a link from Mike Stall's blog - http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top