A more elegant solution to avoid ugly URL's with MCMS
Today I played around a little bit more with HttpModules and implemented a more elegant solution for the problem as discussed in my previous post.
Especially the second problem - normal postback caused by ASP.NET controls - was not properly solved as it required to do the modification on every template file. Using an HttpModule avoids this overhead.
Here is the complete implementation which addresses avoids both problems discussed in the previous article:
using
System;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using Microsoft.ContentManagement.Publishing;
namespace StefanG.HttpModules
{
public class CmsNiceUrlHttpModule : IHttpModule
{
public void Init(HttpApplication httpApp)
{
httpApp.PreRequestHandlerExecute += new EventHandler(this.OnPreRequestHandlerExecute);
}
public void Dispose()
{
// Nothing to do.
}
public void OnPreRequestHandlerExecute(object o, EventArgs e)
{
HttpContext ctx = ((HttpApplication)o).Context;
IHttpHandler handler = ctx.Handler;
// lets correct the ugly URLs when switching between update and published mode
Posting thisPosting = CmsHttpContext.Current.Posting;
PublishingMode currentMode = CmsHttpContext.Current.Mode;
if (thisPosting != null && currentMode == PublishingMode.Published)
{
if ( ctx.Request.QueryString["NRORIGINALURL"] != null &&
ctx.Request.QueryString["NRORIGINALURL"].StartsWith("/NR/exeres") ) // oh so ugly
{
if ( !thisPosting.Url.StartsWith("/NR/exeres") )
ctx.Response.Redirect (thisPosting.Url);
}
}
// to correct the ugly URL problem for normal postbacks we have to register an eventhandler for the
// Init event of the page object. This handler then can register a better client script block as the one in
// the console code
((System.Web.UI.Page)handler).Init += new EventHandler( this.OnInit );
}
public void OnInit(object sender, EventArgs eventArgs)
{
System.Web.UI.Page x = sender as System.Web.UI.Page;
if (CmsHttpContext.Current != null) // valid context?
{
if (CmsHttpContext.Current.Channel != null) // posting or channel rendering script?
{
if (CmsHttpContext.Current.Mode == PublishingMode.Published) // only in published mode!
{
foreach (Control c in x.Controls) // find the form tag and get the ID
{
if (c is HtmlForm)
{
// now lets register our script with the nice URL
x.RegisterClientScriptBlock("__CMS_Page",
"<script language=\"javascript\" type=\"text/javascript\">\n"+
"<!--\n"+
" var __CMS_PostbackForm = document."+c.ID+";\n"+
" var __CMS_CurrentUrl = \""+CmsHttpContext.Current.ChannelItem.Url+"\";\n"+
" __CMS_PostbackForm.action = __CMS_CurrentUrl;\n"+
"// -->\n"+
"</script>\n");
break;
}
}
}
}
}
}
}
}