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” +
                “</script>\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” +
    “</script>\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:
http://blogs.technet.com/stefan_gossner/archive/2006/01/24/418005.aspx

Comments (21)

  1. Jannik Anker says:

    Hi Stefan,

    Not that it matters at all (ie. makes the code fail), but maybe a more logical name for your script block would be AdjustActionForAJAX, not AdjustActionForAXAJ 😉

    Great post, by the way!

  2. Hi Jannik,

    you are absolutly right!

    😉

    Cheers,

    Stefan

  3. Anonymous says:

    Now after MCMS 2002 SP2 has been released I would like to point you again to an article series I have…

  4. Anonymous says:

    Now after MCMS 2002 SP2 has been released I would like to point you again to an article series I have…

  5. ML49448 says:

    I am using ATLAS control UpdatePanel. Apparently, this is not working for some reason. Any ideas why?

    I did put the script registration code on the MCMS template’s Page_Load event.

    Thanks,

    Michael

  6. ML49448 says:

    I try using the ATLAS:UpdatePanel control and it didn’t work. In view mode, it still does a postback by refreshing the page. And in author mode, the edit link for the web author console will not show up when it is clicked. The button on my page is wrapped inside the content of the UpdatePanel.

    Please comment. Thanks.

  7. Michael_Chu says:

    I try using the ATLAS:UpdatePanel control and it didn’t work. In view mode, it still does a postback by refreshing the page. And in author mode, there are more problems. The edit link for the web author console will not show up when it is clicked. The button on my page and the results are wrapped inside the content of the UpdatePanel.

    Please comment. Thanks.

  8. Hi Michael, I don’t know this control. No idea how it works.

    Cheers,

    Stefan

  9. Anonymous says:

    ASP.NET AJAX 1.0 (formerly known as Atlas) has been released. You can download it from here . If you

  10. Hi Stefan,

    Thanks for posting the JavaScript for getting ASP.NET AJAX 1.0 (atlas) to work with MCMS in IE. Any hope to get this working with FireFox?

    Thanks,

    Ahmed

  11. Hi Ahmed,

    sorry I don’t have Firefox installed on any of my boxes.

    I would have expected that it works the same way as the object that needs to be adjusted is one of the AJAX class.

    Did you test it with firefox?

    Cheers,

    Stefan

  12. Chandy says:

    Firefox not installed!!  I expected better from you Stefan! 😛

  13. Ok, I got another hint from Brick Baldwin on how to enable it with Firefox.

    Code above should now work with Firefox as well.

  14. Göran Tänzer says:

    Hi

    i made a similar workaround to fix the non IE url bug. But i faced also another problem regarding non IE browsers.

    If i use a asp:button in an updatepanel to make an AJAX postback on non IE browser only the first postback works "silent". All subsequent postbacks are "full" reloads of the page. The whole page works perfect when replacing the asp:button with asp:linkbutton. Strange!

    Now i replaced my workaround with the new script but this postback problem still occurs.

    Someone else got the same problem?

    regards

    göran

  15. Göran Tänzer says:

    Hi again …

    I found a "solution" for the described problem above.

    I set the UseSubmitBehavior to false which renders an javascript onclick event. Now it works on ie, firefox and opera.

    But i still don’t know why the postbacks after the first one are not "silent".

    regards

    göran

  16. Anonymous says:

    Good news the ASP.NET AJAX framework (previously known as Atlas) has been released – RTM. Other good

  17. Mark Kovalcson says:

    We found that FireFox was actually working properly with AJAX and MCMS, but IE 6 & 7 were still giving us full postbacks.

    Thank you for this solution.

    Stefan, you rock!

  18. Don says:

    Just updated web project to .net 3.5 and am now getting an error on every page that uses this code

    "_InitialAction" is null or not an object

    Any idea how to fix this?

  19. Hi Don,

    it should be _initialAction and not _InitialAction.

    Please check in the code above.

    Cheers,

    Stefan

  20. Don says:

    Yes that’s a typo on my part.  I have removed the entire function as in your original posting and it seems to still work once I converted to .net 3.5 project references.  Am I crazy or is this a case where the framework has fixed a bug that I used to have to work around?

  21. MCMS is only tested with .NET 2.0 and not with higher .NET version.