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.
No comments:
Post a Comment