Stefan Goßner

Senior Escalation Engineer for SharePoint Products and Technologies

How to enable AJAX with MCMS and ASP.NET 2.0 (last update: April 5th, 2007)

I have posted a solution for this problem in a subsection of this article but someone who is just looking on how to get AJAX working in general might not find it easily.

The probem with AJAX is that the client does a silent postback from Javascript using the Microsoft.XMLHTTP COM object. This technique is known as AJAX (Asynchronous Javascript And XML).

This method works perfectly fine on all normal ASP.NET webforms – but unfortunatelly not on MCMS templates or channel rendering scripts. The reason for the problem is that the AJAX implementation in ASP.NET uses the content of the Action property of the current web form – and ASP.NET always renders the a relative link in the action property and not an absolut link starting from the root of the website. Something like this: template.aspx?NRMODE=Published&NRNODEGUID=…

A technique that work perfectly fine for normal ASP.NET pages as the URL in the browser is identical to the URL ASP.NET knows – but a technique that does not work correct with MCMS as MCMS serves friendly URLs to the browser which are rewritten by the ISAPI filter to the ugly URLs. So the browser knows a URL like http://servername/Development/ while the “real” URL for ASP.NET looks as follows: http://servername/templateproject/template.aspx?NRMODE=Published&NRNODEGUID=…

If AJAX does its postback using XMLHTTP it expects to hit the template.aspx file inside the current directory. But for the browser the current directory is inside the /Development channel and not within the templateproject virtual directory. So the browser send the request to a wrong location. You can easily proof this by having a look into your IIS log!

Normal postbacks do usually not experience this problem as MCMS injects some javascript code to correct the URL right before doing a postback to the posting. But this code is not executed from the ASP.NET AJAX code.

To correct this problem you need to add the following code to the Page_Load event of your ASP.NET template file:

            // register a client script that ensures that the action property
            // is correct when AJAX tries to do its postback.
            string script =
                “\n<script type=\”text/javascript\”>\n” +
                ”   if (typeof (__CMS_CurrentUrl) != \”undefined\”)\n” +
                ”   {\n” +
                ”       __CMS_PostbackForm.action = __CMS_CurrentUrl;\n” +
                ”   }\n” +

            Page.ClientScript.RegisterStartupScript(this.GetType(), “AdjustActionForAJAX”, script);

Beside the AJAX implementation coming with ASP.NET 2.0 natively there is now also another implementation available with code name “ATLAS”.

For this implementation you need to add a different script to the Page_Load event:

// add this Script to handle the confusing between CMS and AJAX
// This handle the CMS ugly URL so AJAX knows where to post back to. 
string script = “\n<script type=\”text/javascript\”>\n” +
    “function EndRequestHandlerCMSFix(sender, args) { \n” +
    ”   if (typeof (__CMS_CurrentUrl) != \”undefined\”)\n” +
    ”   {\n” + 
    ”       if(Sys.WebForms.PageRequestManager._instance._form._initialAction.indexOf(\”http://” + Request.Url.Host + “\”, 0) == -1)\n” +
    ”           Sys.WebForms.PageRequestManager._instance._form._initialAction = __CMS_CurrentUrl;\n” +
    ”       else\n” +
    ”           Sys.WebForms.PageRequestManager._instance._form._initialAction = \”http://” + Request.Url.Host + “\”+__CMS_CurrentUrl;\n” +
    ”   }\n”
    “}\n” +
    “EndRequestHandlerCMSFix(null, null);\n” +
    “Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandlerCMSFix);\n” +
Page.ClientScript.RegisterStartupScript(this.GetType(), “AdjustAJAXForCMS”, script);

(Thanks to Brick Baldwin for this hint!)

Another hint: have a look at the following article. The same problem also affects AJAX 1.0: