Title: AJAX in ASP.NET using only HttpHandlers and Javascript
Slug: ajax-in-asp-net-using-only-httphandlers-and-javascript
Date: 2010-06-07 12:26:00
Author: Kartones
Lang: en
Tags: Development, ASP.NET, Javascript
Description: A tutorial on creating AJAX calls in ASP.NET using HttpHandlers and Javascript, bypassing ASP.NET AJAX framework for more control and customization.

 <p>Today, almost every major site includes at least bits of <a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29">AJAX</a> calls, whenever to display a shopping cart, to dynamically load fragments of a page, or to pre-fetch the next images in a slideshow. <a href="http://jquery.com/">jQuery</a>, <a href="http://mootools.net/">mootools</a>, <a href="http://www.prototypejs.org/">prototype</a>... there is an increasing number of Javascript frameworks that, among other things, allow asynchronous calls to fetch data.</p> <p>In .NET, although they are starting to migrate to jQuery (as we can see in ASP.NET MVC), by default when you create a .NET 3.5 website it references the not bad but clumbersome ASP.NET AJAX framework. Although I don't have anything against this practice, sometimes we don't need so much, or we might prefer to do things "our way" and for example communicate with the client site using JSON.</p> <p>So this post is going to be like a small 3 steps tutorial on how to do 100% handcrafted basic AJAX requests using ASP.NET. Then you can so many things to it to make as good as you want.</p> <p> </p> <p><b>Step 1: Build a HttpHandler</b></p> <p>The most efficient way to develop AJAX call handlers in the server side is to use <a href="https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-1.1/5c67a8bd(v=vs.71)?redirectedfrom=MSDN">HttpHandlers</a>. We keep the request context, but we skip all ASP.NET forms additional layers, providing a fast code in exchange of requiring a full implementation and management of the output by us.</p> <p> </p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3449c42b-d472-400a-8e71-cae0c2d8e5e1" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">using</span> System;</li> <li style="background: #f3f3f3"><span style="color:#0000ff">using</span> System.Collections.Generic;</li> <li><span style="color:#0000ff">using</span> System.Web;</li> <li style="background: #f3f3f3"> </li> <li><span style="color:#0000ff">namespace</span> Handlers</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">AJAXHandler</span> : <span style="color:#2b91af">IHttpHandler</span></li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#0000ff">public</span> <span style="color:#0000ff">bool</span> IsReusable</li> <li style="background: #f3f3f3">        {</li> <li>            <span style="color:#0000ff">get</span></li> <li style="background: #f3f3f3">            {</li> <li>                <span style="color:#0000ff">return</span> <span style="color:#0000ff">true</span>;</li> <li style="background: #f3f3f3">            }</li> <li>        }</li> <li style="background: #f3f3f3"> </li> <li>        <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ProcessRequest(<span style="color:#2b91af">HttpContext</span> context)</li> <li style="background: #f3f3f3">        {</li> <li> </li> <li style="background: #f3f3f3">            context.Response.Write(<span style="color:#a31515">"Received "</span> + context.Request.RawUrl + <span style="color:#a31515">" @ "</span> + <span style="color:#2b91af">DateTime</span>.Now.ToLongTimeString());</li> <li>        }</li> <li style="background: #f3f3f3">    }</li> <li>}</li> </ol> </div> </div> </div> <p> </p> <p>Code is quite easy, so just remember to add a reference to <b>System.Web</b> to be able to implement IHttpHandler interface. IsReusable in this case is interesting as we can probably be having lots of requests to the handler.</p> <p> </p> <p><b>Step 2: Plug the handler in a web project</b></p> <p>We will create the website in the third step but doesn't matters as we just need to add a reference to the handler we've just created, and then edit the web.config to add it, under the <font face="Courier New">&lt;configuration&gt; &lt;system.web&gt;</font> node:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:78bb88f8-d020-4a7c-9ff0-a5e658363b59" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">&lt;</span><span style="color:#a31515">httpHandlers</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">verb</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">*</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">path</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">*.ajax</span>"<span style="color:#0000ff"> </span><span style="color:#ff0000">type</span><span style="color:#0000ff">=</span>"<span style="color:#0000ff">Handlers.AJAXHandler, Handlers</span>"<span style="color:#0000ff">/&gt;</span></li> <li><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">httpHandlers</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div> <p>We're configuring our site to enroute all calls that end in <b>.ajax </b>to our handler.</p> <p> </p> <p><b>Step 3: Client side coding</b></p> <p>Finally, we get to the important part: Making async calls from our webpages. The following example is for one page, of course to reuse it you should place all the <font face="Courier New">&lt;script&gt;</font> code inside a .js file and reference it.</p> <p>We're using asynchronous responses using a callback function to not block anything, but yet this is a simple and standard code without advanced checks, no request manager engine, no error handling... </p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d57294ec-936c-4c0e-b942-65d31f97aa64" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>    <span style="color:#0000ff">&lt;</span><span style="color:#a31515">div</span><span style="color:#0000ff">&gt;</span></li> <li style="background: #f3f3f3">        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">div</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">="test_placeholder"&gt;&lt;/</span><span style="color:#a31515">div</span><span style="color:#0000ff">&gt;</span></li> <li>        <span style="color:#0000ff">&lt;</span><span style="color:#a31515">input</span> <span style="color:#ff0000">type</span><span style="color:#0000ff">="button"</span> <span style="color:#ff0000">value</span><span style="color:#0000ff">="Test"</span> <span style="color:#ff0000">onclick</span><span style="color:#0000ff">="javascript:AJAXCall('test.ajax', 'test_placeholder');"</span> <span style="color:#0000ff">/&gt;</span></li> <li style="background: #f3f3f3">    <span style="color:#0000ff">&lt;/</span><span style="color:#a31515">div</span><span style="color:#0000ff">&gt;</span></li> <li>    </li> <li style="background: #f3f3f3"><span style="color:#0000ff">&lt;</span><span style="color:#a31515">script</span> <span style="color:#ff0000">type</span><span style="color:#0000ff">="text/javascript"&gt;</span></li> <li>    <span style="color:#0000ff">var</span> xmlhttpReq;</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">var</span> targetElement;</li> <li> </li> <li style="background: #f3f3f3">    <span style="color:#0000ff">function</span> AJAXCall(Url, Target) </li> <li>    {</li> <li style="background: #f3f3f3">        targetElement = Target;</li> <li>        <span style="color:#0000ff">if</span> (window.XMLHttpRequest) </li> <li style="background: #f3f3f3">        {</li> <li>            xmlhttpReq = <span style="color:#0000ff">new</span> XMLHttpRequest();</li> <li style="background: #f3f3f3">        }</li> <li>        <span style="color:#0000ff">else</span> </li> <li style="background: #f3f3f3">        {   <span style="color:#008000">// code for IE5-6</span></li> <li>            xmlhttpReq = <span style="color:#0000ff">new</span> ActiveXObject(<span style="color:#a31515">"Microsoft.XMLHTTP"</span>);</li> <li style="background: #f3f3f3">        }</li> <li> </li> <li style="background: #f3f3f3">        xmlhttpReq.onreadystatechange = ajax_response;</li> <li> </li> <li style="background: #f3f3f3">        xmlhttpReq.open(<span style="color:#a31515">"GET"</span>, Url, <span style="color:#0000ff">true</span>);</li> <li>        xmlhttpReq.send(<span style="color:#0000ff">null</span>);</li> <li style="background: #f3f3f3">    }</li> <li> </li> <li style="background: #f3f3f3">    <span style="color:#0000ff">function</span> ajax_response() </li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#008000">// 4 completed, 3 in progress</span></li> <li>        <span style="color:#0000ff">if</span> (xmlhttpReq.readyState == 4 &amp;&amp; xmlhttpReq.status == 200) </li> <li style="background: #f3f3f3">        {</li> <li>            <span style="color:#0000ff">if</span> (xmlhttpReq.responseText) </li> <li style="background: #f3f3f3">            {</li> <li>                <span style="color:#008000">// responseText contains output</span></li> <li style="background: #f3f3f3">                document.getElementById(targetElement).innerHTML = xmlhttpReq.responseText;</li> <li>            }</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">else</span></li> <li>            {</li> <li style="background: #f3f3f3">                document.getElementById(targetElement).innerHTML = <span style="color:#a31515">''</span>;</li> <li>            }</li> <li style="background: #f3f3f3">        }</li> <li>    }</li> <li style="background: #f3f3f3"><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">script</span><span style="color:#0000ff">&gt;</span></li> </ol> </div> </div> </div> <p> </p> <p>Each time we click on the button we'll see a timestamped response.</p> <p> </p> <p>From here, you can improve the handler (or add more) to handle JSON, XML, even HTML templates, the limit is your imagination ;)</p>