ASP.NET MVC – Create easy REST API with JSON and XML
Mar 27th, 2009
So I just hopped on the ASP.NET MVC bandwagon. As my first task, I undertook custom Action Filters for returning either JSON or XML as determined by the HTTP Request. Fortunately Omar AL Zabir did most of the work for creating a RESTful API with ASP.NET MVC.
JSON and XML Action Filter Code
The following is a filter which makes the whole thing much cleaner. The filter looks for Content-Type headers in the HTTP request. If it matches text/xml then Plain Old XML (POX) is returned and if it matches application/json the output is JSON. This eliminates the need to write separate actions for JSON/XML and Views.
using System;
using System.Web;
using System.Web.Mvc;
using System.IO;
using System.Xml;
using System.Text;
using System.Xml.Serialization;
namespace AleemBawany.ActionFilters
{
public class JsonPox : ActionFilterAttribute
{
private static UTF8Encoding UTF8 = new UTF8Encoding(false);
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// setup the request, view and data
HttpRequestBase request = filterContext.RequestContext.HttpContext.Request;
ViewResult view = (ViewResult)(filterContext.Result);
var data = view.ViewData.Model;
String contentType = request.ContentType ?? string.Empty;
// JSON
if (contentType.Contains("application/json"))
{
filterContext.Result = new JsonResult
{
Data = data
};
}
// POX
else if (contentType.Contains("text/xml"))
{
// MemoryStream to encapsulate as UTF-8 (default UTF-16)
// http://stackoverflow.com/questions/427725/
using (MemoryStream stream = new MemoryStream(500))
{
using (var xmlWriter =
XmlTextWriter.Create(stream,
new XmlWriterSettings()
{
// Plain Old XML (no XML headers)
OmitXmlDeclaration = true,
Encoding = UTF8,
Indent = true
}))
{
new XmlSerializer(data.GetType()).Serialize(xmlWriter, data);
}
filterContext.Result = new ContentResult
{
ContentType = "text/xml",
Content = UTF8.GetString(stream.ToArray()),
ContentEncoding = UTF8
};
}
}
}
}
}
I suggest you get the code directly through JsonPoxFilter.cs in my SVN repository. It will be updated if I make any improvements.
Usage Example
To use this code in your Controller Action, you simply need to decorate it with the [JsonPox] attribute:
// Depending on HTTP Content-Type header
// this returns JSON, XML or the default View
[JsonPox]
public ActionResult Index()
{
ArrayList stuff = new ArrayList();
stuff.Add("Hello World");
stuff.Add(999);
stuff.Add(1.0001);
ViewData.Model = stuff;
return View();
}
Sample Output
If Content-Type: text/xml HTTP header is present the output is:
<ArrayOfAnyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <anyType xsi:type="xsd:string">Hello World</anyType> <anyType xsi:type="xsd:int">999</anyType> <anyType xsi:type="xsd:double">1.0001</anyType> </ArrayOfAnyType>
For the HTTP header Content-Type: application/json the output is:
["Hello World",999,1.0001]
And if neither of those headers are present, the default View is returned.
Once again, if you intend to use it, get the latest bits for JsonPoxFilter.cs here instead of copying the above code.
Get to see that you finally jumped off of the ASP.NET webforms bandwagon, now when will you fall in love with ORM?
Well, with MVC going RTM it was hard to resist. Web forms are still good for what they do (VS designer, third-party controls, rapid prototyping with automatic handling of sessions states and postbacks) but for my present case, ASP.NET MVC is the better choice.
And now that ADO.NET Entity Framework has also gone RTM, I’m giving it a good, hard look but my inclination is toward Linq to SQL (No NHibernate for now due to lack of jump-start scenarios with MVC or VS 2008).
You should try SubSonic out I think that it flows with MVC a lot more as Rob Conery is now working on MVC and SubSonic.
Thanks, I will certainly check it out.
[...] previously published a JSON / POX Filter for MVC developers working with RESTful services. It works really well in that it allows a [...]
Have a look at my series on creating a RESTful web service using MVC. I’ve implemented XSLT based views, a “Help” representation etc. Hopefully it will be of use to you!
I have perused through your posts but they seems overly complicated for something that should be fairly trivial. Regarding JSON/XML, in part 3 you handle it by having switch statements in your action methods which is tedious and repetitive with a management overhead–it should be done in a common location. Also I am not sure I agree with format type information as a query parameter (?format=json). It doesn’t seem RESTful because that can be inferred by HTTP headers.
The filter here is very easy to implement, you just need to decorate your action methods and that’s pretty much it. You don’t need to write any special code to handle JSON/POX–it just works automatically.
[...] was introduced to the various serialization options in .NET while trying to build the JSON and XML filter for ASP.NET MVC. In this post I’ll take a look at the different JSON serializers in .NET and the reasons to [...]
[...] such as “iPhone” or “XBOX” or “Cablebox”. The article found at http://aleembawany.com/2009/03/27/aspnet-mvc-create-easy-rest-api-with-json-and-xml/ shows a clean way of providing multiple outputs based on ActionResult. We will actually take a [...]
Great tip but I found that when I run this on a POST action e.g.
[AcceptVerbs(HttpVerbs.Post)]
[JsonPox]
public ActionResult DeleteUser(Guid? id)
The ContentType is equal to “application/x-www-form-urlencoded”
Instead, I use request.AcceptTypes[0]
PS: I am using jquery to perform an ajax post e.g.
$.post(url,data,callback,"json")
The content type should not be form-urlencoded if you are serializing the form as json. If it is its will not be handled the by the filter. It’s possible the submit button triggers the submission and preempts the Javascript.
sir i have problem how to create API of Asp.net web applicatoion.
how to registered user of my website view by thirty party website admin.send me soluation with code .reply please sir………….