Introduction
ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework.
Learn here: http://www.asp.net/web-api
Background
By default, Parameter Binding in Web API only allows single [FromBody] parameter. This leads you to create multiple actions or route just to have a workaround.
More information on Parameter Binding can be found here.
If you have used action-based HTTP Route, then this should be suitable for you. Your routing should look something like this one below:
config.Routes.MapHttpRoute(
name: "DefaultActionRoute",
routeTemplate: "api/{controller}/{action}",
defaults: new { id = RouteParameter.Optional },
constraints: new { action = "[^\\.]+" }
);
For example, you need an API URL that will cater to all POST
requests and should be able to accept different objects for whatever reason your project or client required it.
URL:
Acception Content Objects (XML/JSON):
ObjectOne
ObjectTwo
ObjectThree
This will not work:
public HttpResponseMessage Post([FromBody] ObjectOne id,
[FromBody] ObjectTwo name, [FromBody] ObjectThree name) { ... }
To solve this problem, here are some of the handy codes you will need to use to Serialize the object from XML or JSON and the generic method for reading the content.
public static class SerializationHelper
{
public static readonly XmlSerializerNamespaces EmptyXmlSerializerNamespace =
new XmlSerializerNamespaces(new[] { new XmlQualifiedName("") });
public static T DeserializeJson<T>(string jsonString)
{
if (string.IsNullOrEmpty(jsonString))
{
throw new ArgumentNullException("jsonString");
}
return DeserializeJson<T>(new MemoryStream(Encoding.UTF8.GetBytes(jsonString)));
}
public static T DeserializeJson<T>(Stream jsonStream)
{
var jsonSerializer = new DataContractJsonSerializer(typeof(T));
if (jsonStream == null)
{
throw new ArgumentNullException("jsonStream");
}
return (T)jsonSerializer.ReadObject(jsonStream);
}
public static string SerializeToJsonString(object obj)
{
var jsonSerializer = new DataContractJsonSerializer(obj.GetType());
using (MemoryStream buffer = new MemoryStream())
{
jsonSerializer.WriteObject(buffer, obj);
return Encoding.UTF8.GetString(buffer.ToArray());
}
}
public static T DeserializeXml<T>(string xmlString)
{
if (string.IsNullOrEmpty(xmlString))
{
throw new ArgumentNullException("xmlString");
}
return DeserializeXml<T>(new MemoryStream(Encoding.UTF8.GetBytes(xmlString)));
}
public static T DeserializeXml<T>(Stream xmlStream)
{
var xmlSerializer = new XmlSerializer(typeof(T));
if (xmlStream == null)
{
throw new ArgumentNullException("xmlStream");
}
return (T)xmlSerializer.Deserialize(xmlStream);
}
public static string SerializeToXmlString(object obj)
{
XmlSerializer xs = new XmlSerializer(obj.GetType());
using (MemoryStream buffer = new MemoryStream())
{
xs.Serialize(buffer, obj, EmptyXmlSerializerNamespace);
return Encoding.UTF8.GetString(buffer.ToArray());
}
}
}
If you have a base ApiController
, you can include this generic method ReadContentAs<T>()
.
public abstract class BaseApiController : ApiController
{
protected T ReadContentAs<T>()
{
if (Request.Content != null)
{
try
{
if (Request.Content.IsXmlContent())
{
return SerializationHelper.DeserializeXml<T>(
Request.Content.ReadAsStreamAsync().Result);
}
if (Request.Content.IsJsonContent())
{
return SerializationHelper.DeserializeJson<T>(
Request.Content.ReadAsStreamAsync().Result);
}
}
catch
{
return default(T);
}
}
return default(T);
}
}
Using the Code
Using the methods is easy. In your action method, simply call the ReadContentAs<T>()
and voila!
public HttpResponseMessage Post()
{
var details = ReadContentAs<ObjectOne>();
}
You might need an identifier from the URL to match the content.
public HttpResponseMessage Post([FromUri] string command)
{
switch (command)
{
case "add-objectone":
var details = ReadContentAs<ObjectOne>();
case "add-objecttwo":
var details = ReadContentAs<ObjectTwo>();
}
}
Points of Interest
I've been working full time for almost a year now using ASP.NET Web API and there are a few tricks I have learned to meet requirements of clients. I have noticed there are few posts I see on the web so I decided to create this and maybe help someone. This is my first time, so forgive my writing skills.
History