Expose your Existing ASP.NET MVC Actions as JSON/XML API Endpoints

Published on Author nickriggs10 Comments

Often times I’d like to provide simple JSON/XML API endpoints for my web application. When I first started using ASP.NET MVC, I’d create separate actions that would return a JSONActionResult. This worked, but always felt like code bloat in my controllers.

I also am an avid user of view models in my controllers – as models for my views and as parameters for my actions. Usually, my view models have only exactly what is needed for the view or action, and usually look nothing like the underlying model (data entities).

This got me thinking that my existing controller actions were already poised to be my API. I just needed to control the format in which they accepted and returned the view models. So I created MVC API Action Filter some time ago, and recently open sourced it.

As an example, let’s have a Create action that accepts a Person view model, modifies the databases and redirects to the Details action:

[HttpGet]
public ActionResult Create()
{
    return View(new Person());
}

[HttpPost]
public ActionResult Create(Person person)
{
    if (!ModelState.IsValid)
        return View(person);

    _data.Create(person);

    return RedirectToAction("Details", new { id = person.Id });
}

public ActionResult Details(Guid id)
{
    var person = _data.Get(id);

    return View(person);
}

This works fine using the Html form and displaying the details after the post:

Now let’s take the same actions and expose them as JSON/XML API endpoints. To do this, we simply decorate the actions with the [Api] attribute:

[HttpPost]
[Api]
public ActionResult Create(Person person)
...

[Api]
public ActionResult Details(Guid id)
...

To specify the format of the request, we modify the Content-Type header. To specify the format of the response, we modify the Accept header. Let’s use jQuery to demonstrate JSON example:

$.ajax({
   type: "POST",
   contentType: "text/json",
   dataType: "json",
   data: "{"FirstName":"Nick","LastName":"Riggs","Age":30}",
   url: "Home/Create"
});

The response looks like:

{"Id":"52536e05-9433-402b-948b-8560923d34b7","FirstName":"Nick","LastName":"Riggs","Age":30}

An XML example:

$.ajax({
   type: "POST",
   contentType: "text/xml",
   dataType: "xml",
   data: "<Person><FirstName>Nick</FirstName> <LastName>Riggs</LastName> <Age>30</Age></Person>",
   url: "Home/Create"
});

The response looks like:

<Person><Id>cbf6eedd-2147-46fc-925a-a570db7ab68a</Id> <FirstName>Nick</FirstName> <LastName>Riggs</LastName> <Age>30</Age></Person> 

I hope the MVC API Action Filters helps the MVC community. It’s really helped clean up my controllers and create simple APIs for my AJAX calls and even external consumer applications.

Download MVC API Action Filter: http://mvcapi.codeplex.com/
Demonstration: http://examples.nickriggs.com/mvcapi/

10 Responses to Expose your Existing ASP.NET MVC Actions as JSON/XML API Endpoints

  1. Hello! I am using your actionfilter and it works very well with jquery.ajax – if i runt it on the same domain. JsonP however does not seem to work…i also receive 500 internal server error if im using pure Code behind to request my URL. I traced the error to the actionfilter… Send me an email if you are interested in the error logs.

    Anywho, what are you thoughts, will you be publishing an update with jsonp support anytime soon?

    Otherwise, nice work, thanks alot! Peace!

  2. Hi, great API and actively built. Currently I am building this with headace. I will try yours one. Seems good only in Action filter can handle the Json/Xml/Html. but there is few things that can be improved. Like support UTF8 during XML deserialize, override Accept header with file extension if exist (.json/.xml). add “application/xhtml+xml”. If I use your code, I will move the feature from mine one to your API if not exist.

  3. Hi Nick,

    I tried your contrib and I have a stupid problem.
    If i reference the DLL the binding it doens’t works. So “person” has all the properties null.

    Instead if I copy your class ApiAttribute : ActionFilterAttribute etc in my project everything is working fine.

    do you know why?

  4. “имя = значение”недостатки INI формата давно известны:XML allows aiirtrarbly complex levels and nesting, and has standard mechanisms for encoding binary data. INI files are typically limited to two levels (sections and parameters) and do not handle binary data well. Хотя nesting обходиться созданием секций или параметров по схеме Секция.Подсекция.Параметр=’INI rulez’Если учесть что сжимается xml прекрасно то о тяжеловесности (в смысле размера) можно забыть.

Leave a Reply

Your email address will not be published. Required fields are marked *