Ext.NET Ajax Requests: MVC, Web API or ASHX?

When I wrote the book on Ext.NET 2, I often described using ASHX or MVC Controllers (amongst other techniques) for getting data from Ext.NET Stores via AJAX Proxies.

Recently, I’ve received a few questions — and wondered myself — whether to use Web API instead. It has a cleaner method signature, and is intended for this kind of scenario where you want to return data rather than HTML.

I finally got a moment to compare all three (for my scenario).

TL;DR version

  • Any of these approaches work
  • Interestingly, they all perform similarly well
  • In the long run, Web API seems the cleanest, though have some very minor caveats at the moment
  • For now, I would initially go for MVC Controllers because Ext.NET 2 has more support baked in for it than Web API so you can reuse a bit more Ext.NET code.
  • The ASP.NET team is planning to integrate Web API and MVC even more, so I imagine Ext.NET will inevitably support both, minimizing your code changes and making ASP.NET Web API even more likely the preferred option for implementing Ext.NET AjaxProxy handlers.

In more detail

ASP.NET Web API differs from ASP.NET MVC in that while they are both based on Controllers, Web API is intended to share data (e.g. REST or AJAX requests), while MVC is intended to generate web pages (though you can also use it to generate any content just like with Web API).

Using ASHX handlers and MVC Controllers for to get JSON data for Ext.NET Stores via an AjaxProxy are demonstrated both in my book and on the Ext.NET Examples Explorer and Ext.NET MVC Examples Explorer.

Web API has a nicer method signature where you define your parameters and the type of response just like any normal method. By comparison, MVC Controllers follow a convention that typically returns an ActionResult, often a View.

In the case of Ext.NET using MVC Controllers for Store/Ajax Proxies, Ext.NET provides extension methods to return StoreResult, which is a JSON object containing data for the stores, the total record count, success, or failure message, etc.

With Web API, you define your own class to represent the response, but your return type does need to include those properties in a similar way to a StoreResult class so that the Ext JS proxy can understand the response from the server. You can’t unfortunately use or inherit StoreResult because it has custom serialization into JSON, rather than simply serializing the relevant properties on the class using default JSON serialization techniques.

With ASHX, you get more bare metal coding with Requests and Responses, etc, and you can serialize your result back to the response manually, which is easy enough. As with Web API, what you serialize has to be understood by the client side Ext JS proxy, so you do need to have properties for the data, total record count, etc.

Compared to ASPX Web Forms (which you could also use to return JSON), ASHX is far more performant as it by-passes the heavy page lifecycle of Web Forms.

I was curious if MVC Controllers, and Web API Controllers could perform as well as ASHX. My guess was that ASHX would be the fastest, followed by Web API controllers, followed by MVC Controllers. I reasoned that ASHX has the least plumbing to do, while MVC Controllers have a bit more than Web API because of the View handling.

Rather than just go with a hunch, I finally had a time to actually test this out. I am glad I did, because (at least for my scenario) it turned out all 3 performed nearly identically (statistically insignificant differences, from what I could tell).

So, go for Web API, right?

Well, not so fast: unfortunately Web API just has the slightest headache to configure correctly – your method signature may need to support a parameter called action which is passed on the querystring by the Ext JS Ajax proxy (maybe a REST Proxy can be used to avoid this – I didn’t try that out).

Worse, however, it seems that enabling GZip compression for Web API responses is not enabled by default (even if assuming you have enabled the correct IIS features). This is because the mimetype for JSON responses, application/json, is not in the default list of dynamic compression mime types that IIS has which Web API maintains. And it seems you cannot just add it in your own web.config. You have to modfiy applicationHost.config directly, which many people may not be able to do.

It turns out there is a handy NuGet package to compress Web API responses. Unfortunately at the moment its assemblies are not signed, which is a problem for my application unfortunately.

Rather than try the various tricks to work around that, I opted for the other option, to modify applicationHost.config for now – which has to be done in a very specific way – just to get the Web API response compressed so I could carry on with comparing this approach with the ASHX and MVC Controller approaches.

I find this a bit off-putting for the moment. I imagine a future version of IIS will enable the application/json mimetype to be compressed for dynamic content, but for now, you have to bear this in mind.

Also, I think session defaults may be opposite for MVC and Web API – for MVC I think they are enabled by default and not for Web API. In my case, I do not want to rely on session for AJAX data requests (as that can hamper scalability as well due to serialized access to session) so you have to be sure it is turned off if you don’t need it.

Ext.NET 2 has great support built in for MVC. Web API is newer, and over time the .NET team are looking to integrate these two into one anyway, so for now for me it is good to reuse the mechanisms and infrastructure that the Ext.NET team have built around MVC – besides their support is so good that this is another bonus to use what they know in order to get even more rapid responses and remain productive!

Test your own scenario

I should add that while I don’t show any code here, it is worth testing this for your particular scenario as different circumstances may lead you to a different conclusion.

Others have found different results, and it really depends on the many things your application needs (session vs no session, routing complexity, and lots of other things), so you really need to compare your own scenarios.

Hope that helps!