Json responses in a MVC web application


I am sure this is obvious to every web developer using Microsoft’s MVC implementation with asp.net, but for those looking to move from standard asp.net to an MVC platform, this might not come to mind.

The scenario is, you want to provide application data to a browser-side UI (for use with auto-complete textboxes, asynchronously updating UI controls (no server-side post-backs, things you use jQuery or AJAX for.)

You’ve got a few options:

  • ASP.NET Web Service
  • ASP.NET Web Page (.aspx)  that returns raw data with an appropriate content-type
  • ASP.NET HTTP Handler (.ashx) that returns raw data with an appropriate content-type
  • WCF Web Service hosted under IIS
  • in fact there are a ton of custom solutions you could use as well, I’m going to ignore them and stick with the Microsoft family of solutions.

First, I’m going to throw out the ASP.NET Web Page option. Sure you can do it but it’s exactly the same the HTTP Handler but more efficient and only require the “code-behind” portion of a page, not the .aspx portion as you are returning raw data in whatever format (Json, Xml, csv, whatever.)

Now you have to consider your system interaction a bit. If you have multiple applications consuming the data, WCF is most likely the way to go. It supports multiple protocols (http, tcp/ip, msmq, etc.) If you have a native client and a web application consuming the data. It’s the way to go.

A standard ASP.NET Web Service would also be usable by both but would only support HTTP, but since you can get that functionality with a WCF service, it’s the way things are moving in Microsoft Land. Having said that, configuration of the services, behaviors, end-points is a pain in the @$$! From experience I can say it was easy to use the proxy classes generated by the service proxy but I am having a very hard time getting it to accept HTTP GET requests. If this was any of the other of the options, it would have been a no brainer (due to their limitations.) Complex problems take complex configuration solutions, nature of the beast.

It’s worth mentioning that native client’s can also consume http web services relatively easily, so if you have a lot of knowledge investment in standard web services and you only need to support web based clients then this isn’t a wrong choice at all.

If you find yourself in a situation where only your web application is going to be consuming your application data you can fall through to the simplest form. Make a Page or Handler in your application and directly serve it. Tapping in to get or post variables, cookies, session, it’s all there at your fingertips. It’s my favorite when I only have to worry about feeding the UI due to it’s ease of use.

Enter the land of MVC

First let’s just get it over with, you absolutely can use a .ashx page in a MVC web application on ASP.NET. You will need to add a new route to send it traffic but after that it works the same.

But since that flies in the face of MVC’s “do it this way, you’ll be happier in the end” (as some like to call “Best Practices” Smile) How can you do it the way MVC wants you to.

Simply as it turns out!

Well, first you make a new Controller and give it an Action. For my case I made a DataServiceController with a Action of “GetClientByLastName”. That does the work of fetching the data.

My model is a string containing a List of Client POCO classes which has been serialized to Json (through the magic of .NET 4.0’s inclusion of DataContractJsonSerializer.) so I don’t need a custom model.

Then make a view with no format and not strongly typed and simply @HTML.Raw() write it out. You’ll also want to set the page response’s content-type to reflect what you’re be outputting. I did this in the Controller, I’m sure there are more way to do it.

Anyway, in the end, using easily coded, standard MVC stuff, I am able to get a Json fromatted list of client’s to work with from my UI simply by fetching from:

[warning, this link won’t resolve] http://mydomin.com/clients/min

And I get a list of at most 20 client’s whose last name begin with “min”. Slick enough for me. Anyway hope it helps, I’ll update this when I have some code samples but the concept is easy. I’m embarrassed it took me so long to put two and two together.