GitHub repository now available

Introduction

In ASP.NET, we have something that is usually overlooked that is called Generic Handlers. I see a lot o f people using pages to process AJAX requests when we can use this much less expensive
endpoint.
This is an completely worked out Generic Handler that truly knows how to handle your http (AJAX and not) requests.

Background

For a long time I used plain Generic Handlers (ASHX files) to handle my AJAX requests but it felt stupid and painful.
I mean, the functionality was there but the whole process of handling the requests wasn't straight forward.
So I made a list of the things I would like to have and now it's already a lot more than that.

NEW v2.5!

Fully supports collections as requests arguments

Nested collections are fully supported

Native and Complex item types supported

Improved support for complex types as method arguments

Improved HTTP verbs filter

New HTTP verbs filter attributes (DELETE and PUT)

Improved controller Help (more to come soon)

Improved performance (still working to further improve this)

Performance improvements are always a work in progress. From the simple tests I've done this controller already performs at the same level as the ASP.net MVC controllers.

New PerformanceTest.aspx added to main demo project

New ASP.net MVC project created for performance comparison with MVC controllers

This project isn't added to the solution. Add if you want to use it.

Small refactoring and improvements all around

NEW v2.0!

OnMethodInvoke and AfterMethodInvoke virtual methods

These allow the possibility to intersect the execution before and after the method call

public void SetResponseContentType(ResponseContentTypes value)

Easy way to set the response content type from the enum

Specify supported HTTP verbs by handler and by method

Now we can specify if a method only supports certain HTTP verbs by simply decorating the method with the related Attribute

Default methods for main HTTP verbs (GET, POST, PUT and DELETE)

If no method is passed the handler will call the method related with the Request HTTP verb.

These methods can me overrided to implement your logic.

Response serialization improvements (JSON and XML)

You can now use the returntype parameter on the Request to specify how you want your response data without having to modify your code.

The default is JSON but you can also pass XML or HTML.

The default serialization can be disabled on method scope.

Performance optimization

v1.1

Support for complex objects as method argument

Now you can put your custom classes on the handler methods arguments.

Automatically hydrates the class and all its nested types!!

v1.0

Standard way to parse the query string

Transparently handle multiple methods within the same handler

Support methods with multiple typed arguments, not just strings

Support Methods that receive lists as an argument

Support passing less arguments than the method is expecting (like optional parameters)

Transparently reply either POSTs or GETs

Support default object serialization to JSON but still let me override it on each method

Return application/json by default but still let me override it on each method

Support jQuery $.ajax request

Support request by query string (URL right on the browser)

A way to visualize the methods the handler supports (like webservices do)

Extensible

Using the code

I'm working to improve this documentation.
Until then, all you need to know is on the Default.aspx of the demo project.

List the Handler methods

I've provided a very basic way of listing the methods the Handler exposes.
This is specially useful to test if the handler is working correctly (like on webservices).
Do do so just append ?help at the end of the handler URL:

http://localhost/mydemohandler.ashx?help

Calling the Handler from the browser URL

Using this handles is very simple:

Create a new Generic Handler

Clear everything inside the handler class

Inherit from my Handler class

DONE! Now you only need to add your methods.

Let's create a very simple example that receives a name and returns a string (see on the project).

Writing a method that returns HTML

Like I said on my intention points above, I need to have some methods that return whatever I want like HTML, XML, images, files, etc...
The default behavior of the handler is to return JSON so, by method, we need to explicitly say that we want to handle things our way.
For that just use these lines anywhere within the method:

Optional Parameters and nullable types

All parameters in the methods are optional. If they're not passed their default value is assigned.
Also all parameters can be nullable. In this case the default value will be null.

Support for complex types

Say you have a JSON object and a class server side that maps it. Hydrating this class server side is a pain. Usually we pass each property as an argument of the method on the Handler, instantiate a new instance of the class and set the properties one by on... a pain right?
NO MORE! This handler now supports automatic class instance creation and property set. Something I like to call Object Hydratation! " />
And there's more! If this class have properties that also expose other custom classes they will be hydrated too!!
Just make sure all classes have a public default constructorr

Comments and Discussions

Hi Alex and thanks for this great piece of code.
I think I'm having a problem though. If I don't set the response content type to json manually then the response is served as text/html by default. This happens regardless of how i call the handlers method (tried manually from the browser, jquery's getJSON etc) You mention that the default response content type is json. Am I missing something here? Thank you!

Hi!
As I usually use this on my jquery AJAX requests I simply disable the cache right on the request.
I know it doesn't really "disables" the cache, it just add a timestamp at the end of each GET request to make it different and invalidate cache but it works fine

Your idea is great although that configuration must be passed on the querystring... not pretty.

Why query string? Why not some property that could be set in derived class constructor or in method (like you way of disabling default json serialization). If that property is true - add cache disabling headers to response. Something like that =)

Ah ok.
I was seeing that as optional by request.
Doing it on the handler method it self is much easier.

So what you really need is a common place where you can set configurations to all requests to that handler.
The best solution for this and other "problems" is for me to add two virtual methods to the AdvancedHandler:BeforeProcessRequest
Is called before your method

AfterProcessRequest
Is called after your method.

This way you can put those Cache configuration on one of those and you'll be sure that each response will have them.

Using ASP.Net, i'hv developed a master page with a form.
Now, i developed a content page with a form. On submit of content page form button i wana call a generic handler. How can i do this???? Wen a simply do this handler is not called.
I cant pass form action inn master page as this affecting other pages.
Wen i simply developed a page without dis master page den code workin fine.

ASP.net only allows you to have one runat="server" form per page so I believe this is the one you have on the masterpage.
Also runat="server" forms shouldn't have inner forms, and this is why you're having this problem.

My advise to you is to rethink your design. Here are a few tips:Tip 1: Remove the masterpage form and add one on each child page

Tip 2: Leave the masterpage Form around one ContentPlaceHolder and create a new ContentPlaceHolder where you can put a new Form on the child page if needed.

Tip 3: Don't use the Form action, use the button code behind click event.

Sure it can. You can also do it with webpages (ASPX) or anything else that responds to an HTTP request.

The thing here is the ease of use.
A webservice is a stand alone application, it must have its own configuration on IIS and so on. Generic Handlers live inside your application and obey the same permission rules everything else does.

Think about security for example.
AJAX requests are done directly from the client to your server.
If you use webservices you must expose it to the web.
If you're using Forms authentication (or any other kind of authentication) on your site you'll have to ensure that the Webservice also requires that level of security and shares the same security token with the site.

If you use Generic Handlers none of this is a problem because they live inside your application and have the same security rules applied as any other page in there.
If you need to make some public just put them inside a folder with a custom Webconfig file like you would do to a web page.

This is just some problems / extra work you'll have if you decide to use webservices instead of Generic Handlers.

I use Webservices a lot on my SOA projects architecture.
They encapsulate all my modules as a service but they are usually private, not exposed to the public.
When I want to expose a REST API I do it in a specific WCF service and they have their own security mechanisms.

Thanks for asking, I think this is a major point that is missing on the article.

Web services are not necessarily standalone applications, you can have them running inside your pre-existing web app. You can even make adjustments so it returns JSON to make things easier for the javascript piece.

Moreover, you can now use Web API which is a very simple and easy way to achieve what you proposed in this article. Check out Scott Guthrie's latest blog post to see what I'm talking about.

I actually never had an svc inside a web project but sure it should work.
This code I'm publishing here have about 1 year and now it may be starting to have true competitor with this new Web API

I never used MVC Web API but the examples I've seen are too simple and it seems you're not able to pass json objects, only discrete arguments on the request query string.
With my handler you now can pass almost anything as a json object, with inner json objects.
I'm also currently developing v1.2 where I'll be adding support for arrays and generic lists method arguments and possibly method overloading.

This also supports GETs through querystring but when there are too many arguments to pass having the ability to pass a json object is a time saver

I believe Web API will evolve to be something more useful but right now I wouldn't choose it over this handler.

Thank you for your comments mate, they're much appreciated.
One of the main reasons I published this code was to gather feedback from others and evolve it to support other scenarios.

Yes I understand and a year back I would definitely use your approach, in fact I have used something very similar to handle simple tasks like auto complete textboxes, I just thought I should mention new technologies for people who stumble across your article now like I did.

I have to disagree with your opinion on Web API though, there's a lot of awesome stuff you seem to be missing out on - it is actually very much capable of seamlessly parsing json objects into POCO classes and also returning json from these classes with little to no effort from the developer. There's a lecture Scott Guthrie gave on these new technologies that is really worth watching, you can download it from his blog @ http://weblogs.asp.net/scottgu/archive/2012/02/19/asp-net-mvc-4-beta.aspx[^]

I'm looking forward to see v1.2 of your code - I'm currently working on a proprietary client-server communication interface that should allow for serializing generic lists with custom types (dictionaries of custom types are a NIGHTMARE to work with using reflection, you'll see )

Good luck!

Edit: oh and be sure to check out Phil Haack and Scott Hanselman' blogs, they also have very interesting posts on Web API