IIS 7.5 Logging with Sitecore 6.x in Integrated Pipeline Mode

by aboo bolaky 4. December 2010 21:48

When you run Sitecore 6.x in Integrated Pipeline Mode, You will notice that ALL IIS log entries contain the log entry for the resquest to the layout (aspx) page (instead of the actual sitecore item .e.g /ContactUs.aspx).

This problem is partly related to another issue outlined on Stack Overflow  [http://stackoverflow.com/questions/353541/iis7-rewritepath-and-iis-log-files]

If you run Sitecore in Classic Mode, the problem disappears. However, if you still wish to use Integrated Pipeline Mode, you will have to intercept the request  before the Sitecore HttpModule (Sitecore.Nexus.dll) gets involved.


Create a class that extends System.Web.IHttpModule  and  set the path back to the original value after the request has been processed but before the IIS logging module writes the log entry.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace Test
    public class RewritePath : IHttpModule
        public void Init(HttpApplication context)
            context.BeginRequest += OnBeginRequest;
            context.LogRequest += OnEndRequest;

        static void OnBeginRequest(object sender, EventArgs e)
            var app = (HttpApplication)sender;
            app.Context.Items["OriginalPath"] = app.Context.Request.Path;

        static void OnEndRequest(object sender, EventArgs e)
            var app = (HttpApplication)sender;
            var originalPath = app.Context.Items["OriginalPath"] as string;
            if (originalPath != null)

        public void Dispose()



Locate the Modules Section (under system.webServer ..remember we’re running in Integrated Pipeline Mode) and plug the module in BEFORE the Sitecore Nexus HttpModule


Here's what's captured when everything is compiled and deployed


Thanks Sitecore Support.

Tags: ,

.Net | Applications | Sitecore | Tips & Tricks

Missing Icons in Page Edit Mode in Sitecore 6.1

by aboo bolaky 25. November 2010 05:29

I remember, back in the days when I was using Sitecore 6 in Page Edit mode, an blue arrow would highlight the placeholders on the page when I would hover the placeholder name in the in Design Pane.

Now that I'm using Sitecore 6.3, I've realised that this was no longer the case. The only thing that happens is the description of the placeholder (new cool thing !) is displayed at the bottom of the page.

After spending several hours with IE Developer Toolbar (yes..IE Developer Toolbar !!!.. I couldn't use Firefox/Firebug because the Design Mode is not currently supported in Firefox), it finally came down to this :

To make life easier (allegedly) and boost the performance (again...allegedly), all icon files for Sitecore (initially in Directory (sitecore\shell\Themes\Standard) have been zipped up and automatically extracted on the fly when you select an icon from the Icon Choose Screen.. Well that's a good thing..BUT...

The webedit.css (which, I hear you say, is responsible for styling the injected spans that the Page Editor introduces) still references icons/files in the "Themes\Standard" folder.


Well, since those files are now zipped up, they will no longer be available and thus won't appear on Page Edit Mode.


There are about 10 url references (e.g background:url (/sitecore/shell/themes/standard/Applications/32x32/arrow_right_blue.png) in the webedit.css. Extract the required icons from their respective zipped archives, and change the background url references accordingly

Once this is done, everything was back to normal and we were all happy again.. What a day !! :)




ListView with DataPager problem in .Net 4

by aboo bolaky 31. October 2010 00:36

I wanted to set the QueryStringField property of the DataPager dynamically. By default, if you do not specify this property, the pager works on a Postback Model.

On the other hand, if you do set the QueryStringField to something, it'll use the value that you set the QueryStringField to as a query string parameter and assign it the appropriate page number (IOW, it makes use of a query string parameter to change the page view)

The declarative and code-behind files are simple enough..



public partial class _Default : System.Web.UI.Page
        public string FieldName
                return "PageID";
        protected override void OnInit(EventArgs e)
            ListView1.PagePropertiesChanging += new EventHandler(ListView1_PagePropertiesChanging);
            DataPager1.QueryStringField = FieldName;

        void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
            DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);

        protected void Page_Load(object sender, EventArgs e)
            if (!this.IsPostBack)

        private void BuildAndBind()
            ListView1.DataSource = BuildDataSource();

        private List BuildDataSource()
            Person a = new Person { FirstName = "A", LastName = "A", Address = "Address1" };
            Person b = new Person { FirstName = "B", LastName = "B", Address = "Address2" };
            Person c = new Person { FirstName = "C", LastName = "C", Address = "Address3" };
            Person d = new Person { FirstName = "D", LastName = "D", Address = "Address4" };
            Person e = new Person { FirstName = "E", LastName = "E", Address = "Address5" };
            Person f = new Person { FirstName = "F", LastName = "F", Address = "Address6" };
            Person g = new Person { FirstName = "G", LastName = "G", Address = "Address7" };
            Person h = new Person { FirstName = "H", LastName = "H", Address = "Address8" };
            Person i = new Person { FirstName = "I", LastName = "I", Address = "Address9" };
            Person j = new Person { FirstName = "J", LastName = "J", Address = "Address10" };
            Person k = new Person { FirstName = "K", LastName = "K", Address = "Address11" };
            Person l = new Person { FirstName = "L", LastName = "L", Address = "Address12" };
            Person m = new Person { FirstName = "M", LastName = "M", Address = "Address13" };

            List list = new List();

            return list;

So far...So good..

Using the above example, since we've set the property in the code behind, we'd expect the pager to use a query string to drive the page view. Commenting the line out forces the pager to use a postback model.

What about .Net 4?

the above situations work when the project is set up to run in .NET 3.5 . However, this solution does not seem to work with .NET 4.0 at all. If we set the Target Framework to 4.0, the paging does not work if we want to force a QueryStringField at runtime :(

I've  attached a copy of the vs2010 website here

TestWebApp.zip (2.44 kb)

and the video (in mp4 format...) here

DataPager.mp4 (5.27 mb)

If there's anyone out there who can give me a clue on what's right or wrong, please drop me a few lines.. :)



.Net | Asp.Net

Indexing PDF documents with Lucene and Sitecore

by aboo bolaky 14. January 2010 06:32

Getting Lucene to index pdf document is a doddle, thanks to the document published on SDN. if you follow the instructions to the letter, you will be able to make Lucene index pdf documents in no time

HOWEVER, please be aware that you have to properly dispose the objects (to name a few... PDDocument and Ikvm.io.InputStreamWrapper objects) after you parsed the document(s).

If you forget to do so, you will soon notice that your temp folder (c:\windows\temp) will be filled with pdfbox temp files (e.g pdfbox124bb19809ftmp). In the worst case scenario, the C drive runs out of disk space => no website.

Original Code Published on SDN

private string ParsePDF(MediaItem mediaItem)
        Stream stream = mediaItem.GetMediaStream();
        ikvm.io.InputStreamWrapper wrapper = new ikvm.io.InputStreamWrapper(stream);
        PDDocument doc = PDDocument.load(wrapper);
        PDFTextStripper stripper = new PDFTextStripper();
        return stripper.getText(doc);


Revised Code

private string ParsePDF(MediaItem mediaItem)
        PDDocument doc = null;
        ikvm.io.InputStreamWrapper wrapper = null;

            Stream stream = mediaItem.GetMediaStream();
            wrapper = new ikvm.io.InputStreamWrapper(stream);
            doc = PDDocument.load(wrapper);
            PDFTextStripper stripper = new PDFTextStripper();
            return stripper.getText(doc);
        catch (Exception Ex)
            //[some logging here] ..
            return String.Empty;
            if ((doc != null) && (wrapper != null))


Rebuild the index and have a good night sleep :)


Playing God with Windows 7

by aboo bolaky 7. January 2010 08:52

This is going to be a quick one.

To enable "GodMode" on Windows 7, create a folder on your desktop and rename it to the following:


The icon for the folder automatically changes to a "system-settings-like" icon. From there, you can basically manage EVERYTHING on your pc..

Go on...Give it a try.

Thanks Bro. 



I'm a PC

by Aboo Bolaky 2. November 2009 00:42

and Windows 7 was MY IDEA !!!


The AByss

Registering XSLT Extension Objects with the ASP XML control

by aboo bolaky 23. October 2009 07:01

I once inherited a sublayout that inlcuded an asp:xml control. The asp:xml control was there to handle and display an xml feed from another system, while the rest of the sublayout concentrated on rendering related feed content from Sitecore. The presentation of the xml feed was handled via an xlst rendering.

In this particular situation, I made use use of XSL extensions in the XSLT file. Registering the XSL Extension was fairly easy.

	<extension mode="on" type="Utils.XslHelper, Utils"
		   singleInstance="true" />

Registering the extension in the xsl file

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 exclude-result-prefixes="MyExtension" >

<xsl:value-of select="MyExtension:HelloWorld()" />

Binding the XML control to the XML Data

protected override void OnInit(EventArgs e)
        if (!this.IsPostBack)
            string xmlContent = "xml data goes here";
            XsltArgumentList list = new XsltArgumentList();
            Utils.XslHelper ext = new Utils.XslHelper();
            list.AddExtensionObject("http://www.sitecore.net/Utils", ext);
            Xml1.TransformArgumentList = list;
            Xml1.DocumentContent = xmlContent;

It turns out that, even though I had previously registered the xsl extension in the xslt file, I also had to register it via code as well. Otherwise, the following exception occurs at runtime.

Cannot find the script or external object that implements prefix 'MyExtension'.


Tags: ,

.Net | Asp.Net | Sitecore | Tips & Tricks

Retrieving the DATA folder installation path from MS SQL Server using T/SQL

by aboo bolaky 10. October 2009 19:57

This would be useful for creating databases using SQL scripts. The SQL query below returns the installation path of the DATA folder for the installed SQL Server.

SQL Script


DECLARE @device_directory NVARCHAR(520)

SELECT @device_directory = 
	SUBSTRING(filename, 1, CHARINDEX(N'master.mdf', LOWER(filename)) - 1)
FROM master.dbo.sysaltfiles 
WHERE dbid = 1 AND fileid = 1

print @device_directory


C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\


The AByss | Tips & Tricks

Bold style for matching results with AutoCompleteExtender - Implemented using a Trie

by aboo bolaky 7. October 2009 18:22

This article will focus on the implementation of the AjaxControlToolkit's AutoCompleteExtender into a simple ASP.NET application. What I'm trying to do here is pull the data from a database and use the AutoCompleteExtender to display the data as the user types characters in a textbox.

Server Implementation

Im not going to focus on how to retrieve the data (from a table of around 60,000 records). I'm going to use the simplistic SQLConnection/SQLCommand/SQLDataReader classes and passing sql command as plain text (as opposed to Stored Procedures). The key issue is how and what is the best way to store the data once being retrieved. Generally, Autocomplete comes in 2 flavours:-

1: Find words based on letters anywhere in a phrase (performing a LIKE '%ar%'  in SQL).

2: Find words that start with specific characters ( LIKE 'ar%' in SQL).

In the first instance, you're pretty much tied up to using the LIKE clause (be it in a stored proc or simple text). The determining factor here is how and when to cache the data since each character typed in invokes the webservice and queries the database. Each query will yield a different result set.

In the second instance (the focus of this article), the more you add characters to the keyword, you are, in fact, narrowing down the scope of search. This means that the data we initially load is deterministic and hence we can cache it somewhere. But the real deal here is :which  data structure do we hold our words in? List<>, DataTable, Linked List??


You might have already figured this one out. Anyway, a trie is an ordered tree data structure (a.k.a prefix tree) that stores the information about the contents of each node in the path from the root to the node, rather than the node itself. What this means is that each part between the root and any leaf represents a key and the goal is to find the key by traversing the tree.


Eyal Mey-Tal has implemented a Trie structure in C#.Head to the CodePlex site to download it.

WebMethod to retrieve data

    public string[] GetNames(string prefixText, int count)
        Trie trie = (Trie)Context.Cache["Trie"];
        if (trie == null)
            trie = new Trie();
            using (SqlConnection con = new SqlConnection("server=(local);database=autocomplete;user id=xxx;Password=xxx;"))
                SqlCommand cmd = new SqlCommand("select word from AutoCompleteData", con);
                cmd.CommandType = System.Data.CommandType.Text;
                SqlDataReader dr = cmd.ExecuteReader();
                if (dr.HasRows)
                    while (dr.Read())
            //simple caching here  
            Context.Cache["Trie"] = trie;
        List list = trie.GetCompletionList(prefixText);
        return list.Take(count).ToArray();


Setting up the AutoCompleteExtender was easy. To get the autocomplete working, I only had to modify a few of the extender's attributes (.e.g. CompletionSetCount, TargetControlID, ServicePath, ServiceMethod, DelimiterCharacters ..) and data was being returned as I typed in characters. However, making the extender look good was a different story.

Client-Side Implementation 

This is the bit where I'm open to suggestions. I'm no Javascript/JQuery expert but however, I finally got the extender working as I wanted it to. Characters relevant to the ones the user has typed become highlighted in the drop down list. It took me a while to dig this solution out. The javascript is awkward and needs to be refactored. Netherless, the solution works for IE and Firefox [ good enough for me :) ]


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AutoComplete.aspx.cs" Inherits="AutoComplete.AutoComplete" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
            margin: 0px !important;
            background-color: inherit;
            color: windowtext;
            border: buttonshadow;
            border-width: 1px;
            border-style: solid;
            cursor: 'default';
            overflow: auto;
            height: 200px;
            text-align: left;
            list-style-type: none;
            padding-left: 1px;
        /* AutoComplete highlighted item */
            background-color: #aaff90;
            color: black;
            padding: 1px;
            cursor: hand;
        /* AutoComplete item */
            background-color: window;
            color: windowtext;
            padding: 1px;
    <script type="text/javascript">

        function acePopulated(sender, e) {

            var behavior = $find('AutoCompleteEx');

            var target = behavior.get_completionList();
            if (behavior._currentPrefix != null) {
                var prefix = behavior._currentPrefix.toLowerCase();
                var i;
                for (i = 0; i < target.childNodes.length; i++) {
                    var sValue = target.childNodes[i].innerHTML.toLowerCase();
                    if (sValue.indexOf(prefix) != -1) {
                        var fstr = target.childNodes[i].innerHTML.substring(0, sValue.indexOf(prefix));
                        var pstr = target.childNodes[i].innerHTML.substring(fstr.length, fstr.length + prefix.length);
                        var estr = target.childNodes[i].innerHTML.substring(fstr.length + prefix.length, target.childNodes[i].innerHTML.length);
                        target.childNodes[i].innerHTML = "<div class='autocomplete-item'>" + fstr + '<B>' + pstr + '</B>' + estr + "</div>";


        function aceSelected(sender, e) {
            var value = e.get_value();
            if (!value) {
                if (e._item.parentElement && e._item.parentElement.tagName == "LI")
                    value = e._item.parentElement.attributes["_value"].value;
                else if (e._item.parentElement && e._item.parentElement.parentElement.tagName == "LI")
                    value = e._item.parentElement.parentElement.attributes["_value"].value;
                else if (e._item.parentNode && e._item.parentNode.tagName == "LI")
                    value = e._item.parentNode._value;
                else if (e._item.parentNode && e._item.parentNode.parentNode.tagName == "LI")
                    value = e._item.parentNode.parentNode._value;
                else value = "";
            var searchText = $get('<%=txtWord.ClientID %>').value;
            searchText = searchText.replace('null', '');

            sender.get_element().value = searchText + value;
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    <div style="text-align: center; margin-top: 200px">
        Search :
        <asp:TextBox ID="txtWord" runat="server" AutoComplete="off" Width="200px" />
    <cc1:AutoCompleteExtender runat="server" BehaviorID="AutoCompleteEx" ID="autoComplete1"
        TargetControlID="txtWord" ServicePath="MyService.asmx" ServiceMethod="GetNames"
        MinimumPrefixLength="1" CompletionInterval="1000" EnableCaching="true" CompletionSetCount="20"
        CompletionListCssClass="autocomplete_completionListElement" CompletionListItemCssClass="autocomplete_listItem"
        CompletionListHighlightedItemCssClass="autocomplete_highlightedListItem" OnClientPopulated="acePopulated"
        OnClientItemSelected="aceSelected" DelimiterCharacters=";" ShowOnlyCurrentWordInCompletionListItem="true">





The source code (with database script in ~/App_Data (around 60,000 records )) can be downloaded below.

AutoCompleteVS2008Sln.zip (4.84 mb)

Enjoy ....


.Net | Asp.Net | Tips & Tricks

Building extension-less Urls in Sitecore

by aboo bolaky 4. October 2009 08:55

Our goal here is to build a Sitecore solution having links without the .aspx extension.(although accessing a page with a .aspx extension should STILL work)

To start ,you need

  • Helicon ISAPI Rewrite Lite (the free one). Since I'm usingWindows 7 RC1 x64bit, I'll need to download the x64 bit flavour of Helicon Lite
  • A test Sitecore Application .. I will be using the Sitecore Starter Kit [Sitecore Starter Kit 6.0.0 rev.090203] as an my starting point.  (installed on IIS 7).

Before I start on implementing the solution, a little bit of background info would, I guess, be quite useful.

AddAspxExtension in LinkManager

A potential solution is to change the value of AddAspxExtension from true (by default) to false. If you do change it to false, you will have to create a wildcard script map to the ASP.NET runtime. This causes IIS to intercept every request made against the web server. This includes requests for images, asp.net pages and HTML pages. Therefore, enabling a wildcard script map to ASP.NET does have performance implications. If you wish to find another way to use pages without .aspx extensions in Sitecore, please read further....

Sitecore Aliases

Aliases, in a nutshell, allow you to shorten the url of an item. For example, if your item is currently accessible via http://hostname/MyParentItem/MyChildItem.aspx, you can specify an alias of myChildItem, which will be a placeholder for the actual item as it is in the Sitecore tree. Hence, the url of the alias is http://hostname/MyChildItem.aspx. For SEO purposes, this allows us to surface items from deep down in the hierarchy right up to the site root.


  • Aliases do not work if you remove the .aspx extension
  • No matter how far your items are in the sitecore tree, an alias allows you to refer to it from the site root.

Step 1: Install and Configure Helicon ISAPI Rewrite Lite

Start by installing Helicon ISAPI Rewrite. This process is fairly straightforward. Since we are using the lite version,  our Regex entries will be placed in the global http.conf (located in the Lite version installation folder). The entries in my httpd.conf are as follow:-

RewriteEngine on
RewriteBase /
RewriteRule ^(sitecore.*)$ $1 [L]
RewriteRule ^([^\.\?]+)/?(\?.*)?$ /$1.aspx$2 [L]


Url Rewriting Rationale

Before a request is forwarded to Sitecore, the ISAPI module intercepts it.

Line 1: You NEED that ! This turns on the Helicon ISAPI Module

Line 2: Errr...This is self-explanatory..

Line 3: We don't need to chop off the .aspx when we are in Sitecore CMS. For this reason, we're basically telling the module to not do anything when a request has "sitecore" in it.

Line 4: This is the most important bit. This appends .aspx (and querystrings,if any) to requests and consequently forwards the resulting request to Sitecore. Two scenarios arise as a result of this.

 3.1 : Sitecore maps the request to an item in the database. The page gets displayed in the end.

 3.2 : Sitecore cannot find the item based on the url. You will either end up with the  Sitecore's "Item Not Found" page.


Before we go any further, I need to confess that I did modify the Starter Kit a little prior to this operation. Basically, when you load the starter kit, you are greeted with a dummy home Site, that has a nice layout and there is a link to the Actual Starter Site. I was tired of this as my home page, So, I changed the value of "startItem" [in the Sites Definition of website (in web.config)] from "/home" to "/Sample". In that way, when i hit the website, I will eventually land on the real starter site!. Also, by doing so, all my urls within the website will no longer contain "/sitecore/content/.." since the Start Item has changed.

Quick Test on Urls

Request : http://sitecorestarterkit/References.aspx  [OK]

Request : http://sitecorestarterkit/References  [OK]

Request : http://sitecorestarterkit/Services/Architectual-Services.aspx [OK]

Request : http://sitecorestarterkit/Services/Architectual-Services [OK]

Request : http://sitecorestarterkit/Sitecore/  [OK..CMS access]

It looks like we have a half-baked solution. Aliases will now work without the .aspx extension as well. The other bits that need to be considered are

1 : How to make sitecore controls (.e.g. sc:link etc..) aware that they should drop the ".aspx" extensions

2 : How does it all tie up together with .NET (user controls etc..)

Step 2: XSL Extensions (revised)

To follow up on custom solution, you will need to tell Sitecore to remove the ".aspx" when it renders urls (either via sc:link [xsl extensions] or c# code). For XSL Extensions, we need to disable the default implementation that Sitecore provides us with and roll out our own. Fortunately, it's very easy to do so. [Credits : Chris Wojciech ]


2.1 : Turn off the default XslHelper

<!-- Changed from "On" to "Off" -->
<extension mode="off" type="Sitecore.Xml.Xsl.XslHelper, Sitecore.Kernel" 
	namespace="http://www.sitecore.net/sc" singleInstance="true" />



2.2 : Create your own XslHelper

 namespace Starterkit.Utils
	 public class XslHelper : Sitecore.Xml.Xsl.XslHelper
		public override string path(System.Xml.XPath.XPathNodeIterator iterator)
			string path = base.path(iterator);
			string newPath = Regex.Replace(path, ".aspx", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled);
			return newPath;
		public override string link(string fieldName, System.Xml.XPath.XPathNodeIterator iterator, string parameters)
			string path = base.link(fieldName, iterator, parameters);
			string newPath = Regex.Replace(path, ".aspx", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled);
			return newPath;
		public override string StartLink(System.Xml.XPath.XPathNodeIterator iterator, string parameters)
			string path = base.StartLink(iterator, parameters);
			string newPath = Regex.Replace(path, ".aspx", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled);
			return newPath;


For each of those three methods, we're only replacing the .aspx with an empty string. To enable <sc:link/> to use our custom Xsl Helper, we need to add another entry to the <xslextensions> section


	<!-- Changed from "On" to "Off" -->   
	<extension mode="off" type="Sitecore.Xml.Xsl.XslHelper, Sitecore.Kernel" 
	namespace="http://www.sitecore.net/sc" singleInstance="true" />  
	<extension mode="on" type="Starterkit.Utils.XslHelper, Starterkit.Utils"
	 namespace="http://www.sitecore.net/sc" singleInstance="true" />


NEARLY THERE!!!. All the links (that are rendering using sc:link) have now lost the .aspx extensions on the front end.

Step 3 : Sitecore and .NET interaction (with Url Rewriting)

If you have a Sitecore solution built using XSLT renderings only (highly unlikely though..), you're kinda safe here. However, if you have usercontrols (that host controls that can cause a postback) as well (for argument's sake, a contact us form), you end up with one issue.

Let's create a Contact Us form and add it to the presentation of the Contact Us item in Sitecore


User Control Designer

 <%@ Control Language="c#" AutoEventWireup="true"
 Codebehind="~/layouts/Starter Kit/Sublayouts/ContactUs.ascx.cs" %>
 <asp:Label Text="First Name : "  AssociatedControlID="txtFirstName" runat="server" />
 <asp:TextBox ID="txtFirstName" runat="server" />
 <asp:Label Text="First Name : "  AssociatedControlID="txtFirstName" runat="server" /> 
 <asp:TextBox ID="TextBox1" runat="server" />
 <asp:Button ID="btnSend" Text="Send" runat="server" />


Page Source

 <form name="mainform" method="post"
 action="/Contact.aspx" id="mainform">

To solve this, you will need to create a Control Adapter for the Forms in your application. Control Adapters allow you to inject custom code within the rendering of a control.


Form Control Adapter

namespace Starterkit.Utils
	public class FormActionRewriter : System.Web.UI.Adapters.ControlAdapter
		protected override void Render(System.Web.UI.HtmlTextWriter writer)
			base.Render(new RewriteFormHtmlTextWriter(writer));
	class RewriteFormHtmlTextWriter : HtmlTextWriter
		public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
			: base(writer)
			this.InnerWriter = writer.InnerWriter;
 		public RewriteFormHtmlTextWriter(System.IO.TextWriter writer)
			: base(writer)
			base.InnerWriter = writer;
		public override void WriteAttribute(string name, string value, bool fEncode)
 			if ((name == "action"))
				HttpContext Context = null;
				Context = HttpContext.Current;
				if (Context.Items["ActionAlreadyWritten"] == null)
					if ((!Context.Request.RawUrl.Contains("sitecore")))
					{   //remove .aspx extension if we're on the front end
						value = Regex.Replace(Context.Request.RawUrl, ".aspx", String.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled);
						Context.Items["ActionAlreadyWritten"] = true;
			base.WriteAttribute(name, value, fEncode);

Add Form Control Adapter in Solution

Open the form.browser (located in ~/App_Browsers) and add the new entry

	<browser refID="Default">
			<adapter controlType="System.Web.UI.HtmlControls.HtmlForm" 
			adapterType="Sitecore.Web.FormAdapter, Sitecore.Kernel" />  
			<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
			adapterType="Starterkit.Utils.FormActionRewriter, Starterkit.Utils" />    


<form name="mainform" method="post"
 action="/Contact" id="mainform">


RESULT !!! .... Back to Sitecore :)

Tags: ,

.Net | Applications | Sitecore

Tag cloud

Flash Player 9 required.

About Me

I wish I could write something here..
//TODO: ElaborateMe