9E070F68CCDB4EC2B8FEB5A6D8172E7E
  • RedDot CMS Blog
  • 25.10.2019
  • EN

rdb: ASPX PostBacks in CMS

We mostly do ASPX .net web sites in Open Text Management Server, and it has always bothered me that the pages don’t operate properly inside the CMS, so the other day I decided to figure out what the problems were and try to make it work. Turns out it’s actually quite easy so I thought I’d share.

The Problem

Postbacks won’t work in SmartEdit because the page isn’t being served in its natural state from ASPX, even in CMS 10. The form post target contains the internal CMS URL of the page, not the SmartEdit URL.
 

The Solution

%ProgramFiles%\OpenText\WS\MS\ASP\RDServer.ini

It is necessary to ensure that the temporary ASPX files generated for SmartEdit and Preview modes are persisted, as these are our postback targets. To do this we need to alter a setting in the RDServer.ini file. Changes to this file do not require RedDot to be reset, they take effect immediately in most cases. Alter the Flags setting as follows:

flags=1024 
flags=1280

The semi-colon in front of the original value makes the line into a comment so that the value is ignored by the system.

%PreExecuteTemp%web.config
%ProgramFiles%Open TextWSMSASPweb.config

The config files in your pre-execute temp and CMS directories need to disable event validation and view state MAC since the page posts will be crossing application domains. If your CMS directory doesn’t have a web.config file it is safe to create one. Ensure the pages element contains attributes as follows:

<configuration>
    …
    <system.web>
        …
        <pages enableEventValidation="false" enableViewStateMac="false">
            …
        </pages>
        …
    </system.web>
…
</configuration>

 

Template Code

There is 1 critical and a few optional things you’ll need in your template to make postbacks work. We need to redirect the postback to the page that is used to deliver the content. In production that would be the ASPX page itself but inside the CMS it isn’t. Worse still it’s different for Preview and SmartEdit. You’ll need a script block as below as the last thing in your page, just above the </body>:

<script type="text/javascript">
    document.getElementById("form1").action=location.href;
</script>

…assuming your main form has the ID form1 of course.

If your form/control does autopostback on field types that don’t normally support posting you will also require a little server side script block like this:

<script runat="server">
    public void Page_Init(object sender, EventArgs e)
    {
        //this ensures the __doPostBack() JS method is included on the page
        ClientScript.GetPostBackClientHyperlink(this, "");
    }
</script>

…as it says in the comment, this ensures the __doPostBack JS method is included in the page. This will only work if your page has AutoEventWireup set to true.  Also, if you’re using a “User Control” it will need to be Page.ClientScript instead of just ClientScript.

If possible put this into inline code so you can use a SmartEdit Mode block (<!IoRangeRedDotMode>) to remove it for publication. If you need to put in into code-behind you can use the URL to filter out this code at run-time.
 

Finishing Touches – Asynchronous Postbacks

In CMS 10 the user interface makes use of the Microsoft AJAX library, particularly in SmartEdit. This means that you can’t include a ScriptManager in your form without breaking the CMS. See the ScriptManager causes the Microsoft AJAX library to be added too, meaning it is added twice, which screws things up. You need to do two things to fix it.

Template Code – Server-side bit

Put the following into your Page_Init() method, either the inline one that you added just a moment ago, or the one in your code-behind:

//this is required to ensure MicrosoftAjax.js code is not included  
//in the page twice; the path "null.js" is intended to result in a 404  
sm.ResolveScriptReference += new EventHandler<ScriptReferenceEventArgs>( ( obj, args ) => { if ( args.Script.Name.ToLower() == "microsoftajax.js" ) args.Script.Path = "null.js"; } );

This code assumes your ScriptManager has the ID sm. It will re-write the path to the MicrosoftAjax.js that is generated by the ScriptManager to “null.js”, which obviously doesn’t exist, thereby ensuring the MS Ajax library is only loaded once.

Template Code – Client-side bit

Annoyingly there is one method you need to re-write in the Microsoft AJAX framework which controls the async postback target. I haven’t tested thoroughly enough to be sure this doesn’t have any side-effects on the CMS itself so if you see something let me know and I’ll try to work through it.

Essentially we need to direct async calls from Update Panels to the CMS Temp virtual directory rather than the default directory, which is the CMS itself (the current path).

Append the following to the client-side script block at the end of the page (just before the </body>):

//re-write this to use the overloaded version of _resolveUrl with the
//provided base path
Sys.Net.WebRequest.prototype.getResolvedUrl =
    function Sys$Net$WebRequest$getResolvedUrl() {
        if (arguments.length !== 0) throw Error.parameterCount();
            return Sys.Net.WebRequest._resolveUrl(this._url,'http://cms/RDTemp/');
    };

You will need to update the url to match that of your own Pre-Execute Temp virtual directory. The overload for _resolveUrl already exists in the framework but it is always called with the basePath parameter set to null. We are just adjusting that behaviour a little. There may be a way to do that using server-side attributes but I can’t see it at the moment.

       

Downloads

 

QuickLinks

 

Channel