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, and DELETE operations. You would typically pass a single object as a parameter to the PUT and POST action methods. Note that Web API does not support 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 parameters 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 is the updated Web API controller method.
[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.
How to do more in ASP.NET and ASP.NET Core:
- How to use in-memory caching in ASP.NET Core
- How to handle errors in ASP.NET Web API
- How to pass multiple parameters to Web API controller methods
- How to log request and response metadata in ASP.NET Web API
- How to work with HttpModules in ASP.NET
- Advanced versioning in ASP.NET Core Web API
- How to use dependency injection in ASP.NET Core
- How to work with sessions in ASP.NET
- How to work with HTTPHandlers in ASP.NET
- How to use IHostedService in ASP.NET Core
- How to consume a WCF SOAP service in ASP.NET Core
- How to improve the performance of ASP.NET Core applications
- How to consume an ASP.NET Core Web API using RestSharp
- How to work with logging in ASP.NET Core
- How to use MediatR in ASP.NET Core
- How to work with session state in ASP.NET Core
- How to use Nancy in ASP.NET Core
- Understand parameter binding in ASP.NET Web API
- How to upload files in ASP.NET Core MVC
- How to implement global exception handling in ASP.NET Core Web API
- How to implement health checks in ASP.NET Core
- Best practices in caching in ASP.NET
- How to use Apache Kafka messaging in .NET
- How to enable CORS on your Web API
- When to use WebClient vs. HttpClient vs. HttpWebRequest
- How to work with Redis Cache in .NET
- When to use Task.WaitAll vs. Task.WhenAll in .NET