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/
Awesome! Can’t wait to try it out. Thank you.
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!
Nevermind that… i forgot to set the Accept header >.<
Great and simple.
Thanks!
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.
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?
Hi Nick,
i solved the problem, I just rebuilt the project with MVC3 and .NET4
btw great library 🙂
Hi Nick,
Thanks you for listing , so I solved my problem with MVC.
Superb website you have here but I was curious if you knew of any forums that cover the same topics
discussed here? I’d really love to be a part of group where I can get responses from other knowledgeable
individuals that share the same interest.
If you have any recommendations, please let me know.
Bless you!
Feel free to surf to my page my singing monsters hack info
“имя = значение”недостатки 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 прекрасно то о тяжеловесности (в смысле размера) можно забыть.