How to... move from AjaxPro to ASP.NET AJAX PageMethods

Tags: .NET, AJAX, Ajax.NET, ASP.NET, Atlas, JavaScript, Source Code, Web 2.0

In one of my last posts I blogged about the future of Ajax.NET Professional (AjaxPro) and that I'm not able to do further development on that project. A  lot of my readers feeling sad about this but I had to concentrate more on new technologies that will revolutionize web application development.

My recommendation is to move to ASP.NET AJAX because it is Microsoft's next generating ASP.NET web application generation and is built in Visual Studio .NET 2008 (and, of course, available as additional feature pack for Visual Studio .NET 2005. Those of you that are still using .NET framework 1.1: please stay developing with AjaxPro...

 

ASP.NET AJAX PageMethods in VS.NET 2008

When started Visual Studio I start a new WebApplication project:

New Project in Visual Studio .NET

To enable any ASP.NET AJAX feature you need always the ScriptManager which will be responsible for the ASP.NET AJAX main scripts (in AjaxPro prototype.ashx and core.ashx) as well as the JavaScript that is needed to create the client JavaScript proxies (compared with the on-the-fly generated ASHX files in Ajax.NET Professional).

You will find the ScriptManager control in the AJAX Extensions toolbox. Simply drag and drop the control in the default.aspx page.

Visual Studio .NET Toolbox

As this control does not have any UI it will be displayed as a black box in Visual Studio Designer.

ScriptManager

Next we need to setup the ScriptManager. By default PageMethods are not enabled. To enable PageMethods only one property has to be changed. The property name is EnablePageMethods. You can either configure this property in the property list or in the HTML code itself.

EnablePageMethods

That is nearly everything we need to configure in ASP.NET AJAX to get PageMethods running.

Let's have a look at the C# source code that we want to be execute when calling the AJAX method. As a very simple example I will return an integer value. First have a look at the source code that we are currently using in AjaxPro:

namespace WebApplication1 { [AjaxPro.AjaxNamespace("Default")] public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { AjaxPro.Utility.RegisterTypeForAjax(typeof(_Default)); } [AjaxPro.AjaxMethod] public static int HelloWorld() { return 2; } } }

As I have recommended in the Google group for Ajax.NET Professional I'm using the [AjaxNamespace] attribute nearly every time. The reason is that it is very easy to move the class around or to make updates more easy. The [AjaxMethod] attribute marks the static HelloWorld method to be available in the JavaScript client-side proxy.

With AjaxPro you call this method like following line:

<script type="text/javascript"> function callme() { Default.HelloWorld(mycallback); } function mycallback(res) { alert(res.value); } </script>

What do you need to change your code for AjaxPro to ASP.NET AJAX? The code-behind C# source looks very similar. Because we have put the ScriptManager control on the page we don't need the RegisterTypeForAjax call in the Page_Load. The control itselfs has the reference to the page.

The AJAX methods (PageMethods) in ASP.NET AJAX have to be marked with the [WebMethod] attribute. To identify that the Page class includes a method that we want to expose the class has to be marked with the [ScriptService] attribute. That's everything you have to change. Don't forget to change the method to static if not already using static methods.

PageMethods C# source

Wow, that was very easy, no source code change (only meta information are changed). Note that you can still leave Ajax.NET Professional attributes if you want. This makes it very easy to move from AjaxPro to ASP.NET AJAX and back if needed.

On the client-side JavaScript code you have to do more changes but it is not very different. Well, have a look at the JavaScript source code:

<script type="text/javascript"> function onSuccess(value, ctx, methodName) { alert(value + 5); } function onFailed(ex, ctx, methodName) { alert(ex.get_exceptionType()); // get_stackTrace(), get_message(), // get_statusCode(), get_timedOut() } window.onload = function() { var ctx = { CurrentValue: 123456, CurrentDate: new Date() }; // sample context data PageMethods.HelloWorld(onSuccess, onFailed, ctx); } </script>

In the window.onload event I invoke the HelloWorld method. As argument I pass the callback handler if the execution was successful. Another callback handler could be passed to be called if there occurs any problem like http errors or .NET exceptions. As last argument you can pass a context object that will be available in both callback handlers.

If the invoke was successful you get up to three objects. The first will contain the value of the AJAX method, in our example it is the integer 2 (remember in AjaxPro it was res.value). The second passed object contains the context and the last one the method name (which does not include the namespace or class name when e.g. used in MasterPage and Page side-by-side).

The onFailed callback handler will be executed on any error during invocation. As result you get a JavaScript objects with several methods that help you to identify the real error. Second and third passed objects are the same as for the onSuccess callback: the context and method name.

The generation of the JavaScript client-side proxy will be included in the html output:

PageMethods in source

I hope this very short example will help you to move to ASP.NET AJAX. Any questions?

16 Comments

  • B said

    What about global onFailed events...that is one aspect of AjaxPro I loved. I want to just deal with PageMethods.HelloWorld(this.myCallback.bind(this)); And have a default error handler. Can you pass a context object like AjaxPro?

  • Felipe Plets said

    Hello Michael, I'm a Brazilian AjaxPro user, and now i'm moving to ASP.NET AJAX. I've a library in App_code with many of my AjaxPro Methods, I want know if the process to move the methods is the same? In quickly tests I notice I can't access the methods just declaring them like WebMethod and calling with PageMethods. Can you help me? Thanks

  • DieHard said

    This is really sad. :( I'm new to AjaxPro and been using it for the last few months. AjaxPro is fun to work with compare to ASP.NET 2.0 AJAX 1.0 (with poor JSON features). I think people would agree with me can you at least maintain AjaxPro (no more new features). Please at least fix any bugs left and bugs reported by the users. Please fix the this one annoying bug I found reported by Mozilla Firefox Firebug: the timeout in core.ashx

  • William Chang said

    At least maintain AjaxPro (no more new features). Please at least fix any bugs left and bugs reported by the users. Please fix the this one annoying bug I found reported by Mozilla Firefox Firebug: the timeout in core.ashx

  • Igor Ioffe said

    Michael, Thanks a lot for AjaxPro, it's a great product. We build a whole framework around AjaxPro and are debating now should we move to Page Methods or continue using AjaxPro. I have several questions: 1) Can Page Methods let you call the methods of business objects (not in Web Application assembly) 2) What kind of Types are supported as a parameter or return value of the Page Method call? What about custom objects? 3) Are there any provisions for custom converters? Thank you.

  • Rahul said

    Hi Michael, I am an old AjaxPro junkie and am trying to get my stuff to work in the new versions of asp.net 3.5. and your PageMethods. How can I use page methods with rendercontrol(gridview) in a webservice I want to roll my own ajax controls and dont want to use update panels and want the application to be very fast with a small footprint. I am planning to use InnerHTML type of functionality to get the gridview on demand initially and then want to use JSON communication to do the CRUD operations. Any thoughts?

  • Emiliano said

    How can I pass arguments from the javascript function to the AJAX Method (WebMethod) in ASP.NET AJAX? Thanks, great article =)

Comments have been disabled for this content.