Welcome to TechNet Blogs Sign in | Join | Help

ASP.NET 2.0 and MCMS - Try it out - Now even in Authoring Mode!

In my previous article I explained what to do to get a read-only MCMS website working on ASP.NET 2.0. In this article I will go one step further and explain how to get a read-write MCMS website working with ASP.NET 2.0!

First of all you need to ensure that all steps in my previous article are done. After you have ensured that the website works correct as a read-only website follow the rest of this article.

ASP.NET 2.0 creates different html code which is incompatible with the javascript code used by WebAuthor. After playing around for a while with a HttpModule and some web.config settings I finally managed resolve all problems.

To successfully run MCMS 2002 on ASP.NET 2.0 the following http module needs to be added to the web.config:

This http module does two things: it corrects the form tag generated by ASP.NET 2.0 and ensures that it is compatible with the javascript code of MCMS and it replaces some of the javascript code generated by the web author console.

using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using Microsoft.ContentManagement.Publishing;
using Microsoft.ContentManagement.WebControls;


namespace StefanG.ASPNET20_HttpModule
{

    public class ASPNET20_Filter : Stream 
    {
        private Encoding enc = null;
        private bool closed;
        Stream BaseStream;

        public ASPNET20_Filter(Stream baseStream, Encoding encoding)
        {
            BaseStream = baseStream;
            closed = false;
            enc = encoding;
        }
        
        public override void Write(byte[] buffer, int offset, int count) 
        {

            if(Closed) throw new ObjectDisposedException("ASPNET20_Filter");

            string content = enc.GetString(buffer,offset,count);
            byte[] newBuffer = enc.GetBytes(content);
            int pos = content.IndexOf("<form ");
            while (pos >= 0)
            {
                int endpos = content.IndexOf(">",pos);
                int namepos = content.IndexOf("name=",pos);
                int idpos = content.IndexOf("id=",pos);

                // only modify content if name attribute is not present
                if (namepos == -1 || namepos > endpos)
                {
                    pos = idpos+"id=\"".Length;
                    endpos = content.IndexOf("\"",pos);
                    if (endpos > 0)
                    {
                        string idString = content.Substring(pos,endpos-pos);

                        // add a name attribute with the same value as the ID attribute
                        content = content.Insert(idpos,"name=\""+idString+"\" ");

                        newBuffer = enc.GetBytes(content);
                        break;
                    }
                }
                pos = content.IndexOf("<form",pos+1);
            }
            count = newBuffer.Length;
            BaseStream.Write(newBuffer, 0, count);
        }

        public override bool CanRead
        {    
            get { return false; }
        }

        public override bool CanWrite 
        {
            get { return !closed; }
        }

        public override bool CanSeek 
        {
            get { return false; }
        }

        public override void Close() 
        {
            closed = true;
            BaseStream.Close();
        }

        protected bool Closed 
        {
            get { return closed; }
        }

        public override void Flush() 
        {
            BaseStream.Flush();
        }

        public override int Read(byte[] buffer, int offset, int count) 
        {
            throw new NotSupportedException();
        }

        public override long Length 
        {
            get { throw new NotSupportedException(); }
        }

        public override long Seek(long offset, SeekOrigin origin) 
        {
            throw new NotSupportedException();
        }

        public override void SetLength(long value) 
        {
            throw new NotSupportedException();
        }

        public override long Position 
        {
            get { throw new NotSupportedException(); }
            set { throw new NotSupportedException(); }
        }
    } 

    public class ForceMCMScompatibility : IHttpModule 
    {
        public void Init(HttpApplication httpApp) 
        {
            httpApp.PreRequestHandlerExecute += new EventHandler(this.OnPreRequestHandlerExecute);
        }

        public void Dispose() 
        {
            // Nothing to do.
        }

        public void OnPreRequestHandlerExecute(object sender, EventArgs e) 
        {
            HttpContext ctx = ((HttpApplication)sender).Context;
            IHttpHandler handler = ctx.Handler;

            try
            {
                // only take action if we are inside a channel item
                if (CmsHttpContext.Current.ChannelItem != null)
                {
                    // register http filter for ASPNET 2.0 compatibility
                    ASPNET20_Filter aspnet20_filter = new ASPNET20_Filter(ctx.Response.Filter, ctx.Response.ContentEncoding);
                    ctx.Response.Filter = aspnet20_filter;
                }
            
                if ((CmsHttpContext.Current.Posting != null) && 
                    ((WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringNew) |
                     (WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringReedit))) 
                    ((System.Web.UI.Page)handler).Init += new EventHandler(    this.OnInit );
            }
            catch
            {
                // this will happen if the request is in the middle of an expired forms authentication login
                // we just ignore this.
            }
        }

        private const string overrideASPXPostback =
            "\n" +
            "<!-- Updated by ASP.NET compliancy module -->\n" +
            "<!-- Generated by Microsoft.ContentManagement.WebControls.Console -->\n" +
            "<SCRIPT language=\"javascript\" type=\"text/javascript\">\n" +
            "<!--\n" +
            "   var __consoleCachedOriginalPostBack;\n" +
            "\n" +
            "   if( eval(\"window.__doPostBack\") != null )\n" +
            "   {\n" +
            "       __consoleCachedOriginalPostBack = __doPostBack;\n" +
            "       __doPostBack = __consoleCustomDoPostBack;\n" +
            "   }\n" +
            "\n" +
            "   __consoleCachedOriginalOnSubmit = __CMS_PostbackForm.onsubmit;\n" +
            "   __CMS_PostbackForm.onsubmit = __consoleHandleOnSubmit;\n" +
            "\n" +
            "   function __consoleCustomDoPostBack( eventTarget, eventArgument )\n" +
            "   {\n" +
            "       WBC_offWarningBeforeLeave();\n" +
            "       __consoleCachedOriginalPostBack( eventTarget, eventArgument );\n" +
            "   }\n" +
            "\n" +
            "   function __consoleHandleOnSubmit()\n" +
            "   {\n" +
            "       WBC_offWarningBeforeLeave();\n" +
            "       if (__consoleCachedOriginalOnSubmit != null)\n" +
            "       {\n" +
            "           return __consoleCachedOriginalOnSubmit();\n" +
            "       }\n" +
            "        return true;\n" +
            "   }\n" +
            "// -->\n" +
            "</SCRIPT>\n\n\n";

        public void OnInit(object sender, EventArgs eventArgs)
        {
            System.Web.UI.Page currentPage = sender as System.Web.UI.Page; 

            // now lets register our script to correct the missing return value
            currentPage.RegisterStartupScript("OverrideASPXPostback", overrideASPXPostback); 
        } 
    }
}

In addition it is required to add an additional property to the following line in the web.config

   <pages validateRequest="false"/>

It now needs to read as follows:

   <pages enableEventValidation="falsevalidateRequest="false"/>

Important: You should not yet use ASP.NET 2.0 on a production site! ASP.NET 2.0 is not supported by Microsoft without MCMS SP2 installed. The steps above should only be used to evaluate the benefits of ASP.NET 2.0 for a MCMS site now. There is also no guarantee that code developed now for a site as configured above will run without changes after SP2 has been installed!

Published Friday, July 29, 2005 3:48 PM by Stefan_Gossner
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

Saturday, September 24, 2005 9:49 AM by Morten Andreasen

# re: ASP.NET 2.0 and MCMS - Try it out - Now even in Authoring Mode!

Dear Stefan

I am having difficulties to get the "Create Page" and "Resource Manager" dialogues to work on my new ASP.NET 2.0 templates

I get a "Object not set to an instance.." errors.

Have you successfully gotten these dialogues to work?
Saturday, September 24, 2005 11:13 AM by Morten Andreasen

# re: ASP.NET 2.0 and MCMS - Try it out - Now even in Authoring Mode!

I found out myself, the "View as list" and "View as tree" listitems were declared at protected members but they were not tagged with runat=server.

Apparently that vas vaild in .NET 1.1 because they were child object of the DropDownList, but not in 2.0.

Just maske the following two classes, and make the ResourceGalleriesGrid.ascx and TemplateGalleriesBrowse.aspx enherit from them instead.


public class ResourceGalleriesGrid : Microsoft.ContentManagement.WebAuthor.ResourceGalleriesGrid
{
protected override void OnInit(EventArgs e)
{
base.ViewAsList = GalleriesViewSelect.Items[0];
base.ViewAsTree = GalleriesViewSelect.Items[1];
base.OnInit(e);
}
}


public class TemplateGalleriesBrowse : Microsoft.ContentManagement.WebAuthor.TemplateGalleriesBrowse
{
protected override void OnInit(EventArgs e)
{
base.ViewAsList = GalleriesViewSelect.Items[0];
base.ViewAsTree = GalleriesViewSelect.Items[1];
base.OnInit(e);
}

}
Monday, January 09, 2006 11:32 AM by George

# re: ASP.NET 2.0 and MCMS - Try it out - Now even in Authoring Mode!

So how is this http module added to the config file? Can you post the line I need to make this work?
Tuesday, January 10, 2006 8:22 AM by Stefan Goßner [MSFT]

# re: ASP.NET 2.0 and MCMS - Try it out - Now even in Authoring Mode!

Here is the line that needs to be added:

<add type="StefanG.ASPNET20_HttpModule.ForceMCMScompatibility, ASPNET20_HttpModule" name="ForceMCMScompatibility"/>
Friday, February 22, 2008 7:37 AM by Stefan Goßner

# Code Samples

As some of you already noticed: GotDotNet is now down and the code samples previously hosted there have

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker