How to pass multiple parameters to Web API controller methods

Learn how to pass multiple complex objects as parameters to Web API controller methods

postmultiplevalues

In an earlier post here we explored Parameter Binding in Web API. In this post, we will learn how to pass multiple parameters to Web API controller methods.

Web API provides the necessary action methods for HTTP GET, POST, PUT, DELETE operations. You would typically pass a single object as a parameter to the PUT and POST action methods. Note that Web API doesn't support for passing multiple POST parameters to Web API controller methods by default. But what if you were to make a POST request with multiple objects passed as parameter to a Web API controller method?

Understanding the problem

Web API doesn't allow you to pass multiple complex objects in the method signature of a Web API controller method -- you can post only a single value to a Web API action method. This value in turn can even be a complex object. It is possible to pass multiple values though on a POST or a PUT operation by mapping one parameter to the actual content and the remaining ones via query strings.

The following controller class contains a POST method named Save that accepts multiple parameters.

public class AuthorsController : ApiController

    {

        [HttpPost]

        public HttpResponseMessage Save(int Id, string FirstName, string LastName, string Address)

        {

            //Usual code

            return Request.CreateResponse(HttpStatusCode.OK, "Success...");

        }

   }

Now suppose you attempt to call the Web API controller method from JQuery as shown below.

$.ajax({

 url: 'api/authors',

 type: 'POST',

 data: { Id: 1, FirstName: 'Joydip', LastName: 'Kanjilal', Address: 'Hyderabad' },

 dataType: 'json',

 success: function (data) {

alert(data);

}});

Unfortunately, this call will fail as this request cannot be processed by Web API. Similarly, if you have a Web API controller method that accepts multiple complex objects, you would not be able to invoke this method directly from a client in a straight forward manner.

[HttpPost]

public HttpResponseMessage PostAuthor(Author author, string authenticationToken)

{

  //Usual code

  return Request.CreateResponse(HttpStatusCode.OK, "Success...");

}

You can pass parameters to Web API controller methods using either the [FromBody] or the [FromUri] attributes. Note that the [FromBody] attribute can be used only once in the parameter list of a method. To reiterate, you are allowed to pass only one value (simple or complex type) as parameter to a Web API controller method when using the [FromBody] attribute. You can pass any number of parameters using the [FromUri] attribute but that is not the ideal solution in our case.

And now, the solution

Now that we have understood what the problem is when passing parameters to a Web API controller method, let’s explore the possible solutions. One way to achive this is by passing the complex object as a [FromBody] attribute and the string parameter via the Uri as shown in the code snippet below.

$.ajax({

 url: 'api/authors?authenticationToken=abcxyz',

 type: 'POST',

  data: JSON.stringify(author),

 dataType: 'json',

 success: function (data) {

   alert(data);

}});

You would need to modify your Web API controller method accordingly to parse the query string as shown below.

[HttpPost]

public HttpResponseMessage PostAuthor(Author author)

{

  var data = Request.RequestUri.ParseQueryString();

  string criteria = queryItems["authenticationToken"];

  //Usual code to store data in the database

  return Request.CreateResponse(HttpStatusCode.OK, "Success...");

}

Well, but what if you have multiple complex objects to be passed as parameters to the Web API controller method? You can create a single object that wraps the multiple parameters. Refer to the AuthorRequest class given below.

public class AuthorRequest

   {

      public Author Author { get; set; }

      public string Token { get; set; }

   }

Basically, you can wrap multiple parameters in a single class and use this class as a parameter to your Web API controller method.

Here's how the updated Web API controller method would now look like.

[HttpPost]

public HttpResponseMessage PostAuthor(AuthorRequest request)

  {

       var author = request.Author;

       var token = request.Token;

       //Usual code to store data in the database

       return Request.CreateResponse(HttpStatusCode.OK, "Success...");

  }

You can also use JObject to parse multiple parameter values from out of an object.

[HttpPost]

public HttpResponseMessage PostAuthor(JObject jsonData)

{

    dynamic json = jsonData;

    JObject jauthor = json.Author;

    string token = json.Token;

    var author = jauthor.ToObject<Author>();

    //Usual code to store data in the database

    return Request.CreateResponse(HttpStatusCode.OK, "Success...");

}

Another way to solve this is by using FormDataCollection. Incidentally, FormDataCollection is a key / value pair collection much like the FormCollection in MVC.

[HttpPost]

        public HttpResponseMessage PostAuthor(FormDataCollection form)

        {

            var author = form.Get("Author");

            var token = form.Get("Token");

            //Usual code to store data in the database

            return Request.CreateResponse(HttpStatusCode.OK, "Success...");

        }

Thanks to Web API framework extensibility; you can also create your own custom parameter binder by extending the HttpParameterBinding class to provide support for multiple parameter binding.

This article is published as part of the IDG Contributor Network. Want to Join?

To comment on this article and other InfoWorld content, visit InfoWorld's LinkedIn page, Facebook page and Twitter stream.
From CIO: 8 Free Online Courses to Grow Your Tech Skills
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.