How to... use Class Libraries with ASP.NET AJAX like AjaxPro

Michael Schwarz on Wednesday, January 9, 2008

Using Ajax.NET Professional [1] (AjaxPro) you are able to put you AJAX methods wherever you want, if inside the Page class itself, any .NET class in the same project or as a reference class library. To generate the AJAX client-side JavaScript proxies the AjaxPro library checks for all public methods inside a specified type that are marked with the [AjaxMethod] attribute. The only thing you have to add to the Page class (in the Page_Load event) is the call to AjaxPro.Utility.RegisterTypeForAjax(typeof(ClassName)).WebApplication1 - Microsoft Visual Studio

ASP.NET AJAX [2] is using a little bit different way, well, not very different. In the Page class you could add PageMethods [3]. Those PageMethods will be automatically added to the client-side JavaScript proxies when there is a ScriptManager instance available and the EnablePageMethods property is set to true.

If you would like to build a class library in ASP.NET AJAX you have to write a WebService. "Oh, I don't know much about WebService and it is hard to develop those services!" No, that's not true! The only difference compared to AjaxPro is that you have to inherit from System.Web.Services.WebService and use the [WebMethod] attribute instead of the [AjaxMethod] attribute in AjaxPro. The class itself has to be marked with the [ScriptService] attribute.

Note: don't forget to add a reference to System.Web.Extensions and System.Web.Services.

Have a look at the same example as in my last post but using a Class library, now:

<pre style="background-color:White;;overflow: auto;"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/

--><span style="color: #0000FF;">using</span><span style="color: #000000;"> System; </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Web.Services; </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Web.Script.Services; </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.ComponentModel;

</span><span style="color: #0000FF;">namespace</span><span style="color: #000000;"> ClassLibrary1 { </span><span style="color: #008000;">//</span><span style="color: #008000;">[WebService(Namespace = &quot;</span><span style="color: #008000; text-decoration: underline;">http://tempuri.org/</span><span style="color: #008000;">&quot;)] </span><span style="color: #008000;">//</span><span style="color: #008000;">[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] </span><span style="color: #008000;">//</span><span style="color: #008000;">[ToolboxItem(false)]</span><span style="color: #008000;"> </span><span style="color: #000000;"> [ScriptService] </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> Class1 : WebService { [WebMethod] </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">int</span><span style="color: #000000;"> HelloWorld() { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #800080;">2</span><span style="color: #000000;">; } } } </span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

The public method didn't change, only a different attribute is used to mark this public method to be accessible from JavaScript later. The class itself has the [ScriptService] attribute as meta information. You need this because ASP.NET AJAX does not call a real web service. Instead it is using JSON and the XmlHttpRequest JavaScript object. To include the JavaScript proxy you have to include the ASMX file with an suffix /js:

<pre style="background-color:White;;overflow: auto;"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/

--><span style="color: #000000;">http:</span><span style="color: #008000;">//</span><span style="color: #008000;">localhost/WebService1.asmx/js</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

But where do you find the WebService1.asmx? It makes no sense to add a file called WebService1.asmx inside you Class library. What you have to do is to add a new ASMX file in you web application project. The easiest way is to add a new WebService file via Add new item or to simple add a new text file called WebService1.asmx.

Add New Item - WebApplication1

What you have to left inside the file WebService1.asmx is following content:

<pre style="background-color:White;;overflow: auto;"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/

--><span style="background-color: #FFFF00; color: #000000;">&lt;%</span><span style="background-color: #F5F5F5; color: #000000;">@ WebService Language</span><span style="background-color: #F5F5F5; color: #000000;">=</span><span style="background-color: #F5F5F5; color: #800000;">&quot;</span><span style="background-color: #F5F5F5; color: #800000;">C#</span><span style="background-color: #F5F5F5; color: #800000;">&quot;</span><span style="background-color: #F5F5F5; color: #000000;"> Class</span><span style="background-color: #F5F5F5; color: #000000;">=</span><span style="background-color: #F5F5F5; color: #800000;">&quot;</span><span style="background-color: #F5F5F5; color: #800000;">ClassLibrary1.Class1</span><span style="background-color: #F5F5F5; color: #800000;">&quot;</span><span style="background-color: #F5F5F5; color: #000000;"> </span><span style="background-color: #FFFF00; color: #000000;">%&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

Don't forget that you can get rid of all the content in the code-behind source code file. You only need the WebSevice directive and the class name.

The ASP.NET engine knows now that you want to include the class ClassLibrary1.Class1 into this file. Every requests initiated to this file will be processed from your source code in the Class library. Compare this with the RegisterTypeForAjax call in Page_Load when using AjaxPro.

Now, on the client-side JavaScript code you can use nearly the same JavaScript as with AjaxPro. The only difference is the argument list for the AJAX method and the objects passed to the callback handlers. But comparing those methods to PageMethods you will see that they are built on namespaces where PageMethods are only constructed by the object PageMethods and the name of the method.

In our example the JavaScript we used in the last post [3] is very similar. But first we have to include everything we need before. You may remember that ASP.NET AJAX is using a ScriptManager control that will include all the core scripts as well as a reference to the JavaScript client-side proxies. To add a WebService we have to add a ScriptReference.

<pre style="background-color:White;;overflow: auto;"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/

--><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptManager </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">=&quot;ScriptManager1&quot;</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">=&quot;server&quot;</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Services</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ServiceReference </span><span style="color: #FF0000;">Path</span><span style="color: #0000FF;">=&quot;~/WebService1.asmx&quot;</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Services</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">asp:ScriptManager</span><span style="color: #0000FF;">&gt;</span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

The Script reference points to the created WebService1.asmx which itself identifies that it will handle the Class1 in our ClassLibrary1 project. Now you are able to call the methods very similar to AjaxPro and the PageMethods. It looks like a combination of both libraries.

<pre style="background-color:White;;overflow: auto;"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/

--><span style="color: #000000;">&lt;</span><span style="color: #000000;">script type</span><span style="color: #000000;">=</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">text/javascript</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">

</span><span style="color: #0000FF;">function</span><span style="color: #000000;"> onSuccess(value, ctx, methodName) { alert(value </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">5</span><span style="color: #000000;">); }

</span><span style="color: #0000FF;">function</span><span style="color: #000000;"> onFailed(ex, ctx, methodName) { alert(</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">Failed.</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">); }

window.onload </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> ctx </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">; ClassLibrary1.Class1.HelloWorld(onSuccess, onFailed, ctx); }

</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">/</span><span style="color: #000000;">script&gt;</span><span style="color: #000000;"> </span></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com -->

Wow, this was very easy!! And when you know the only difference is in the parameter list for both the AJAX method and the callback handlers you are fine to move to ASP.NET AJAX. Any further questions?