Receiving Data As FormDataCollection in ASP.NET Web API
ASP.NET Web API map HTTP verbs to an action method. The Web API actions must
follow prescribed signatures in order to work as expected. For example, a Web
API method handling POST requests usually takes a single parameter. More often
than not this parameter is of a complex type that wraps the actual pieces of
data in its properties. This arrangement goes well when you know the exact model
being passed by a client (see below).
public string Post(Customer obj)
{
...
}
However, this arrangement is of no use when a client
is sending arbitrary pieces of data not mapping to any model. Luckily, Web API
provides a way to deal with such data. This article discusses just that.
Consider a case where a Web API is expecting data to be inserted in a table
from a client. The data in question consists of arbitrary pieces of information
and can't be mapped to a predefined model class. In such cases you can make use
of FormDataCollection class. The FormDataCollection class resides in
System.Net.Http.Formatting namespace and represents a dictionary of arbitrary
keys and values.
The FormDataCollection class should not be confused with the FormCollection
class of ASP.NET MVC. They reside in different namespaces. The
FormDataCollection resides in System.Net.Http.Formatting whereas FormCollection
resides in System.Web.Mvc namespace.
So, a client can send any number of arbitrary key-value pairs to the Web API
and the Web API will receive them as a FormDataCollection. The following Post()
method of Web API shows how this is done:
public string Post(FormDataCollection form)
{
string customerid = form.Get("customerId");
string company = form.Get("companyName");
string contact = form.Get("contactName");
string country = form.Get("country");
NorthwindEntities db = new NorthwindEntities();
Customer obj = new Customer()
{
CustomerID = customerid,
CompanyName = company,
ContactName = contact,
Country = country
};
db.Customers.Add(obj);
db.SaveChanges();
return "Customer added successfully!";
}
The Post() method shown above takes a parameter of type FormDataCollection.
To read the values from this collection you use Get() method and specify a key
name. In the above code the client is sending Customer details such as
CustomerID, CompanyName, ContactName and Country. Based on these details a
Customer object is formed and added to the Customers DbSet. The changes are
saved to the database using SaveChanges(). The Post() method then returns a
success method to the client.
To call this Web API method you will write the following jQuery code:
$(document).ready(function () {
var data = {};
data.customerID = "ABCDE";
data.companyName = "Company 1";
data.contactName = "Contact 1";
data.country = "USA";
$.post("/api/customer", data, function(msg){
alert(msg);
});
});
As you can see the above code creates a JavaScript object with four
properties - customerID, companyName, contactName and country. Although this
class mimics the Customer model class that's not necessary. You can add any
arbitrary property - value pairs to this object and send it to the Web API.
Once the data object created $.post() method of jQuery is used to call the
Web API and the data object is passed to it. The success function displays the
message returned from the Web API.
If you run this application you will see the customerID, companyName,
contactName and country values in the FormDataCollection.
In the preceding example, you created a JavaScript object and passed it to
the $.post() method. There can be a situation where you need to pass the data
from form fields (rather than from a JavaScript object) to the Web API. For
example, you might be having a web page that renders arbitrary form fields using
jQuery based
on some condition.
<form id="form1">
<input type="text" name="customerId" value="ABCDE" />
<input type="text" name="companyName" value="Company 2" />
<input type="text" name="contactName" value="Contact 2" />
<input type="text" name="country" value="USA" />
</form>
In such cases your $.post() call will change as follows:
$.post("/api/customer", $("#form1").serialize(), function (msg) {
alert(msg);
});
Notice that the second parameter is not a JavaScript object. It's a call to
jQuery serialize() method. The serialize() method returns a URL encoded string
that contains the form field name - value pairs. Upon reaching the Web API this
data can be read into the FormDataCollection as before.