<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>source code bean &#187; ASP.NET</title>
	<atom:link href="http://sourcecodebean.com/archives/category/aspnet/feed" rel="self" type="application/rss+xml" />
	<link>http://sourcecodebean.com</link>
	<description>thoughts and ideas from a .net developer</description>
	<lastBuildDate>Sat, 26 May 2012 09:45:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Serving your ASP.NET MVC site on Nginx / fastcgi-mono-server4</title>
		<link>http://sourcecodebean.com/archives/serving-your-asp-net-mvc-site-on-nginx-fastcgi-mono-server4/1617</link>
		<comments>http://sourcecodebean.com/archives/serving-your-asp-net-mvc-site-on-nginx-fastcgi-mono-server4/1617#comments</comments>
		<pubDate>Tue, 20 Mar 2012 21:20:39 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=1617</guid>
		<description><![CDATA[In my previous post I showed you how to compile and install mono and get your MVC site up running using the development web server xsp4. The next step is to serve your site using a real web server, my choice is nginx. First, we need a configuration file for the nginx site. If you [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://sourcecodebean.com/archives/deploying-your-asp-net-mvc3-site-on-mono/1589">previous post</a> I showed you how to compile and install mono and get your MVC site up running using the development web server xsp4. The next step is to serve your site using a real web server, my choice is nginx. </p>
<p>First, we need a configuration file for the nginx site. If you haven&#8217;t already got nginx installed, install it (<code>sudo apt-get install nginx</code>).</p>
<p>/etc/nginx/sites-enabled/mvc:</p>
<pre>
server {
    listen   80;
    server_name mvctest.sourcecodebean.com;
    root  /home/peter/MonoMvcDeploy/;

    location / {
      root /home/peter/MonoMvcDeploy/;
      index index.html index.htm default.aspx Default.aspx;
      fastcgi_index /Home;
      fastcgi_pass 127.0.0.1:8000;
      include /etc/nginx/fastcgi_params;
    }
}
</pre>
<p><span id="more-1617"></span></p>
<p>Type &#8220;sudo service nginx reload&#8221; to reload the configuration. Browsing to the site should give you a fastcgi error since there is no fastcgi server listening on 127.0.0.1:8000 yet. So far this is a good thing and shows that your configuration is correct. </p>
<p>Next we create a start script for our fastcgi server.</p>
<p>/home/peter/startmvc:</p>
<pre>
#!/bin/bash
source ./monoenv.sh
fastcgi-mono-server4 /applications=/:/home/peter/MonoMvcDeploy/ /socket=tcp:127.0.0.1:8000
</pre>
<p>This is pretty straigt forward, the only thing that might be a bit confusing is this part &#8220;/:/home/peter/MonoMvcDeploy/&#8221;. This means that we want to map the URL / to the application in /home/peter/MonoMvcDeploy/. This allows us to run several applications in the same fastcgi server on different URLs. </p>
<p>Now try running the script and browse to your site, our sample MVC site should appear! </p>
<p>The last step is to create a upstart script to have our application start automatically at system boot</p>
<p>/etc/init/mvc.conf:</p>
<pre>
#!upstart
description "sionmailer web"
author      "peter"

start on startup
stop on shutdown

respawn

script
    echo $$ > /var/run/mvc.pid
    exec sudo -H -u peter /home/peter/startmvc 2>&#038;1
end script

pre-start script
    echo "[`date`] (sys) Starting" >> /var/log/mvc.sys.log
end script

pre-stop script
    rm /var/run/mvc.pid
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/mvc.sys.log
end script
</pre>
<p>Save the config file and start the site: <code>service mvc start</code>. </p>
<p>All done, your site is being served by nginx/fastcgi-mono-server4!</p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/serving-your-asp-net-mvc-site-on-nginx-fastcgi-mono-server4/1617/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deploying your ASP.NET MVC3 site on Mono</title>
		<link>http://sourcecodebean.com/archives/deploying-your-asp-net-mvc3-site-on-mono/1589</link>
		<comments>http://sourcecodebean.com/archives/deploying-your-asp-net-mvc3-site-on-mono/1589#comments</comments>
		<pubDate>Sat, 10 Mar 2012 14:26:49 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Mono]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=1589</guid>
		<description><![CDATA[In this blog post I am going to show you how easy it is to create a new ASP.NET MVC site and deploy it on Linux/Mono. Step 1 &#8211; Create project Create a new ASP.NET MVC 3 project. Compile and run it. Step 2 &#8211; Add assemblies needed by Mono Add references: System.Web.WebPages System.Web.WebPages.Deployment System.Web.WebPages.Razor [...]]]></description>
			<content:encoded><![CDATA[<p>In this blog post I am going to show you how easy it is to create a new ASP.NET MVC site and deploy it on Linux/Mono. </p>
<p><strong>Step 1 &#8211; Create project</strong><br />
Create a new ASP.NET MVC 3 project. Compile and run it.</p>
<p><a href="http://sourcecodebean.com/wp-content/uploads/2012/03/CreateProject.png"><img src="http://sourcecodebean.com/wp-content/uploads/2012/03/CreateProject.png" alt="" title="CreateProject" width="700" class="aligncenter size-full wp-image-1595" /></a></p>
<p><span id="more-1589"></span><br />
<a href="http://sourcecodebean.com/wp-content/uploads/2012/03/2-CreateProject.png"><img src="http://sourcecodebean.com/wp-content/uploads/2012/03/2-CreateProject.png" alt="" title="2 CreateProject" width="400" class="aligncenter size-full wp-image-1596" /></a></p>
<p><a href="http://sourcecodebean.com/wp-content/uploads/2012/03/3-Up-and-running.png"><img src="http://sourcecodebean.com/wp-content/uploads/2012/03/3-Up-and-running.png" alt="" title="3 Up and running" width="700" class="aligncenter size-full wp-image-1597" /></a></p>
<p><strong>Step 2 &#8211; Add assemblies needed by Mono</strong><br />
Add references:<br />
System.Web.WebPages<br />
System.Web.WebPages.Deployment<br />
System.Web.WebPages.Razor</p>
<p><strong>Step 3 &#8211; Copy local</strong><br />
Make sure to set &#8220;Copy Local&#8221; to True for all of the following assemblies:<br />
System.Web.Helpers<br />
System.Web.Mvc<br />
System.Web.Razor (C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies\System.Web.Razor.dll)<br />
System.Web.Routing<br />
System.Web.WebPages<br />
System.Web.WebPages.Deployment<br />
System.Web.WebPages.Razor</p>
<p><a href="http://sourcecodebean.com/wp-content/uploads/2012/03/4.-Copy-local.png"><img src="http://sourcecodebean.com/wp-content/uploads/2012/03/4.-Copy-local.png" alt="" title="4. Copy local" width="435" height="629" class="aligncenter size-full wp-image-1598" /></a></p>
<p>Remove Entity Framework and other unnecessary assemblies. </p>
<p><strong>Step 4 &#8211; Publish your site</strong><br />
Publish it to a directory and copy it to your Linux server</p>
<p><strong>Step 5 &#8211; Get latest Mono and compile it from source</strong><br />
I run Ubuntu 11.10 on my server. Ubuntu has Mono 2.10.6 in its repository, which is quite new, but Mono is moving so fast so I recommend getting the latest version and compiling it from source. The latest version at the time of writing is 2.10.8. <a href="http://www.integratedwebsystems.com/2011/08/install-mono-2-10-3-on-ubuntu-using-bash-script/">Nathan Bridgewater has created a script</a> to simplify this process, if you are running Ubuntu, this is what you will need to run to install Mono:</p>
<pre>
mkdir mono-2.10
cd mono-2.10
wget --no-check-certificate https://github.com/nathanb/iws-snippets/raw/master/mono-install-scripts/ubuntu/install_mono-2.10.sh
chmod 755 install_mono-2.10.sh
./install_mono-2.10.sh
</pre>
<p>It will take a while to compile it, so now is the time to go grab a cup of coffee. </p>
<p><strong>Step 6 &#8211; Run your site with xsp4</strong><br />
Mono have a development web server called xsp4, the first thing we are going to do is to run our site in xsp4 to make sure it works. Mono has been installed to /opt, but does not exist in our PATH, so before we can run Mono we need to setup the mono enviroment variables. To do that I found a script somewhere on the internets, monoenv.sh:</p>
<pre>
MONO_PREFIX=/opt/mono-2.10
export DYLD_LIBRARY_FALLBACK_PATH=/lib:
export LD_LIBRARY_PATH=/lib:/opt/mono-2.10/lib:
export C_INCLUDE_PATH=/include:/include
export ACLOCAL_PATH=/share/aclocal
export PKG_CONFIG_PATH=/lib/pkgconfig:/lib/pkgconfig
export PATH=/bin:/opt/mono-2.10/bin:$PATH
</pre>
<p>At your bash prompt type: source monoenv.sh</p>
<p>Now cd into the directory where you have your published web site and run xsp4. </p>
<p><a href="http://sourcecodebean.com/wp-content/uploads/2012/03/6.-Running-on-mono.png"><img src="http://sourcecodebean.com/wp-content/uploads/2012/03/6.-Running-on-mono.png" alt="" title="6. Running on mono" width="655" height="564" class="aligncenter size-full wp-image-1600" /></a></p>
<p>Now your MVC site should be up running on Mono! </p>
<p>In my next blog post I will cover how to configure your site to run using Nginx and the fastcgi-mono server.</p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/deploying-your-asp-net-mvc3-site-on-mono/1589/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MVC 3 RTM Install Error (after upgrading to VS2010 SP1)</title>
		<link>http://sourcecodebean.com/archives/mvc-3-rtm-install-error-after-upgrading-to-vs2010-sp1/977</link>
		<comments>http://sourcecodebean.com/archives/mvc-3-rtm-install-error-after-upgrading-to-vs2010-sp1/977#comments</comments>
		<pubDate>Thu, 24 Mar 2011 18:28:54 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=977</guid>
		<description><![CDATA[Yesterday I installed Visual Studio 2010 SP1 on my home computer. After the installation I wanted to upgrade MVC3 to the RTM version (I had the RC version installed), so i uninstalled the RC and downloaded the new version. The installation came half way, then stopped, in the log file i found this: Installation failed [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I installed Visual Studio 2010 SP1 on my home computer. After the installation I wanted to upgrade MVC3 to the RTM version (I had the RC version installed), so i uninstalled the RC and downloaded the new version. The installation came half way, then stopped, in the log file i found this:</p>
<p><strong><em>Installation failed with error code: (0&#215;80070643)</em></strong></p>
<p>Not very helpful, but at least something to google. Then I found <a href="http://blog.mjjames.co.uk/2010/12/mvc-3-rc2-install-error-0x80070643.html">this</a> blog post. The author describes pretty much the same issue that I had, so I did what he suggested, unpacked the installer using 7-Zip and installed the MSI packages in the following order:</p>
<ol>
<li>1. aspnetwebpages.msi</li>
<li>2. aspnetwebpagesvs2010tools.msi</li>
<li>3. aspnetmvc3.msi</li>
<li>4. aspnetmvc3vs2010tools.msi</li>
<li>5. nuget.msi</li>
</ol>
<p>This happily installed MVC3 without complaining. Thanks Michael! </p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/mvc-3-rtm-install-error-after-upgrading-to-vs2010-sp1/977/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>First steps toward EPiServer and ASP.NET MVC</title>
		<link>http://sourcecodebean.com/archives/first-steps-toward-episerver-and-asp-net-mvc/595</link>
		<comments>http://sourcecodebean.com/archives/first-steps-toward-episerver-and-asp-net-mvc/595#comments</comments>
		<pubDate>Mon, 19 Apr 2010 20:33:38 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=595</guid>
		<description><![CDATA[Recently I started a new assignment at a customer where we are going to build their new public web site and their intranet, both of them based on EPiServer CMS 6. The person leading the project is very found of ASP.NET MVC, so my first task was to experiment with EPiServer and ASP.NET MVC, to [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I started a new assignment at a customer where we are going to build their new public web site and their intranet, both of them based on EPiServer CMS 6. The person leading the project is very found of ASP.NET MVC, so my first task was to experiment with EPiServer and ASP.NET MVC,  to try to get a running prototype up. </p>
<p>I did some research online to see what others had done. I found two great posts by <a href="http://joelabrahamsson.com/entry/episerver-and-mvc-retrieving-current-page-using-a-custom-model-binder">Joel Abrahamsson</a> and one from <a href="http://fbrz.wordpress.com/2009/10/10/episerver-and-mvc/">Fabio Fabrizio</a>, who based his solution on Joels experiments. </p>
<p>Joels first attempt was to create a base class from which all Controllers inherited. However, this made the controller do more than it should and made it very hard to test. His second attempt was to create a custom model binder and make every action receive currentPage as a parameter. This approach makes it much easier to create unit tests for the code, since it is now possible to moc the currentPage parameter. </p>
<p>Fabio took a different approach and decided to implement a custom MVC handler and a controller factory. This approach fits very well with MVC and felt like the right way to go, so I decided to create a prototype based on Fabios code. Fabios code was based on EPiServer CMS 5 and ASP.NET MVC 1.0, but I wanted to use EPiServer 6 and ASP.NET MVC 2.0, so I started porting the solution.</p>
<p>Porting the solution to EPiServer 6 and ASP.NET MVC 2.0 required some changes to both code and configuration, which not all of them was trivial. At the moment I have a prototype up running, and it works remarkably well! I will continue my experiments and post my results.</p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/first-steps-toward-episerver-and-asp-net-mvc/595/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>EPiServer friendly URLs for paginated pages (and why the asp:LinkButton must die)</title>
		<link>http://sourcecodebean.com/archives/episerver-friendly-urls-for-paginated-pages-and-why-the-asplinkbutton-must-die/510</link>
		<comments>http://sourcecodebean.com/archives/episerver-friendly-urls-for-paginated-pages-and-why-the-asplinkbutton-must-die/510#comments</comments>
		<pubDate>Mon, 15 Mar 2010 06:05:37 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=510</guid>
		<description><![CDATA[Recently I got a request from a customer to perform some search engine optimizing for an old EPiServer site we are maintaining. One of the optimizations was to fix the paging on their product page. The products are fetched from an external data source and are not stored as pages in EPiServer, thus normal EPiServer [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I got a request from a customer to perform some search engine optimizing for an old EPiServer site we are maintaining. One of the optimizations was to fix the paging on their product page. The products are fetched from an external data source and are not stored as pages in EPiServer, thus normal EPiServer paging controls can not be used. Image a normal paging control like this:</p>
<p>Prev 1, 2 , 3, &#8230;, 99 Next</p>
<p>A fairly normal approach to this would have been to use a query parameter for handling the paging. Like this:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&lt;a href=&quot;/products/?page=4&quot;&gt;4&lt;/a&gt;</div>
</li>
</ol>
</div>
<p>By using this approach each page would have a unique entry point, using query strings is however not optimal for SEO, but even worse is using asp:LinkButtons. <span id="more-510"></span>Whoever created the site had decided to use asp:LinkButtons. LinkButtons are very convenient to work with in ASP.NET, but the HTML code they generate is not very SEO friendly. This is the HTML that was generated:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&lt;div id=&quot;ctl00_MainContent_pnlPaging&quot;&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;a id=&quot;ctl00_MainContent_rptPages_ctl00_lbPage&quot;
</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp;href=&quot;javascript:__doPostBack(&#8216;ctl00$MainContent$rptPages$ctl00$lbPage&#8217;,&#8221;)&quot;&gt;1&lt;/a&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;a id=&quot;ctl00_MainContent_rptPages_ctl01_lbPage&quot;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;href=&quot;javascript:__doPostBack(&#8216;ctl00$MainContent$rptPages$ctl01$lbPage&#8217;,&#8221;)&quot;&gt;2&lt;/a&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &lt;a id=&quot;ctl00_MainContent_rptPages_ctl02_lbPage&quot;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;href=&quot;javascript:__doPostBack(&#8216;ctl00$MainContent$rptPages$ctl02$lbPage&#8217;,&#8221;)&quot;&gt;3&lt;/a&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;a id=&quot;ctl00_MainContent_lbNext&quot;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;href=&quot;javascript:__doPostBack(&#8216;ctl00$MainContent$lbNext&#8217;,&#8221;)&quot;&gt;Next&lt;/a&gt;
</div>
</li>
<li class="li2">
<div class="de2">&lt;/div&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>We can see that:</p>
<ul>
<li>LinkButtons generates a javascript that is run when the link is clicked, instead of using a normal link</li>
<li>Paging is handled using a postback, the pages will no longer have unique entry points.</li>
</ul>
<p>This is <strong>disastrous </strong>from a SEO perspective.</p>
<p>So lets fix it. First step is to replace the LinkButtons with normal links (asp:Hyperlink) &#8211; and then we are going to do some URL rewrite magic to create SEO-friendly URLs. The code behind was changed to assign links like <code>/products/?page=4</code>.</p>
<p>Now, to get URLs like <code>/products/page/4</code>, we can create a custom url rewrite module in EPiServer. First we create a new class, Rewrite,  that inherits from <code>EPiServer.Web.FriendlyUrlRewriteProvider</code>. In this class we override three methods (don&#8217;t ask we why they have such confusing names, someone at EPiServer must have been under the influsene of something when nameing them):</p>
<ul>
<li><code>ConvertToInternalInternal </code>- Used to convert from <code>/product/page/4/</code> to an internal EPiServer page with the page id as a query parameter</li>
<li><code>ConvertToExternalInternal </code>- Used to convert from an internal EPiServer URL (<code>/PageType.aspx?lotsofqueryparameters=values</code>) to an external (<code>/products/page/4/</code>)</li>
<li><code>ConvertToInternal </code>- Needed to work around URL rewrite caching behaviour in EPiServer, will get into more detail on this later.</li>
</ul>
<p>This is the class:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">namespace Utils</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">public class Rewrite : FriendlyUrlRewriteProvider <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// The regexp to match a paged url</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="kw4">string</span> _regexpPaging = @<span class="st0">&quot;(.+)/page/([0-9]+)/$&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; protected override bool ConvertToInternalInternal<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; UrlBuilder url, ref object internalObject<span class="br0">&#41;</span><span class="br0">&#123;</span>&#8230;<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; protected override bool ConvertToExternalInternal<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; UrlBuilder url, object internalObject, Encoding toEncoding<span class="br0">&#41;</span><span class="br0">&#123;</span>&#8230;<span class="br0">&#125;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; public override bool ConvertToInternal<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; UrlBuilder url, out object internalObject<span class="br0">&#41;</span> <span class="br0">&#123;</span>&#8230;<span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p><br/></p>
<p>The first method we implement is the ConvertToInternalInternal which will convert the URL to an internal EPiServer URL.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">protected override bool ConvertToInternalInternal<span class="br0">&#40;</span>UrlBuilder url, ref object internalObject<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>url == <span class="kw2">null</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Regexp to match if the URL ends with /page/{Id}/</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; Match match = Regex.<span class="me1">Match</span><span class="br0">&#40;</span>url.<span class="me1">Path</span>, _regexpPaging<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="co1">// If we have a match, remove the /page/{Id}/ from the end of the URL</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// and add a querystring to the internal URL that is dqcPagingId </span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// (should have a unique name to not clash with some other querystring)</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>match.<span class="me1">Length</span> &gt; <span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; url.<span class="me1">Path</span> = match.<span class="me1">Groups</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">Value</span> + <span class="st0">&quot;/&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; url.<span class="me1">QueryCollection</span><span class="br0">&#91;</span><span class="st0">&quot;dqcPagingId&quot;</span><span class="br0">&#93;</span> = match.<span class="me1">Groups</span><span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span>.<span class="me1">Value</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; base.<span class="me1">ConvertToInternalInternal</span><span class="br0">&#40;</span>url, ref internalObject<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Now when the /page/{Id}/ is removed from the URL, and the querystring is added, we can let EPiServer do its normal URL-rewriting.</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">return</span> base.<span class="me1">ConvertToInternalInternal</span><span class="br0">&#40;</span>url, ref internalObject<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p><br/></p>
<p>While not nessesary, we should override the <code>ConvertToExternalInternal </code>as well. This will let EPiServer automatically convert internal urls containing the <code>dqcPagingId </code>querystring to a external url ending with /page/{Id}/.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">protected override bool ConvertToExternalInternal<span class="br0">&#40;</span>UrlBuilder url, object internalObject, Encoding toEncoding<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="co1">// First let EPiServer convert the internal URL to an external. This will give us a URL like:</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="co1">// /Products/?dqcPagingId=5 (if it is a paged page)</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp;bool isRewritten = base.<span class="me1">ConvertToExternalInternal</span><span class="br0">&#40;</span>url, internalObject, toEncoding<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Check if the URLs query string contains dqcPagingId</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// If it does we add /page/{Id} to the URL and removes the query string</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>url.<span class="me1">Query</span>.<span class="me1">Contains</span><span class="br0">&#40;</span><span class="st0">&quot;dqcPagingId&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; url.<span class="me1">Path</span> = <span class="kw4">string</span>.<span class="me1">Concat</span><span class="br0">&#40;</span>url.<span class="me1">Path</span>, <span class="st0">&quot;page/&quot;</span>, url.<span class="me1">QueryCollection</span><span class="br0">&#91;</span><span class="st0">&quot;dqcPagingId&quot;</span><span class="br0">&#93;</span>, <span class="st0">&quot;/&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; url.<span class="me1">QueryCollection</span>.<span class="me1">Remove</span><span class="br0">&#40;</span><span class="st0">&quot;dqcPagingId&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">return</span> isRewritten;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p><br/></p>
<p>Now one can think we would be done, but there is one more method we need to implement. EPiServer uses a cache to cache URL rewrites from external URLs to internal URLs, but it will only cache the querystrings used by EPiServer, not the <code>dqcPagingId </code>we added. This gives a rather unexpected result. The first time the page is loaded everything loads fine, from code behind we can access the <code>dqcPagingId </code>and show the requested page. If you wait 10 senconds (default cache time) or more and reloads the page, it works fine. But if you reload the page sooner, the dqcPagingId will not be set when the page loads. This is because the querystring <code>dqcPagingId </code>is not cached by EPiServer. This took me quite some time to figure out.</p>
<p>The solution to the problem is to override ConvertToInternal to bypass the default caching:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">public override bool ConvertToInternal<span class="br0">&#40;</span>UrlBuilder url, out object internalObject<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// If the URL end on /page/{id}/, bypass cache by calling ConvertToInternalInternal</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; <span class="co1">// A more optimal solution would be to perform some kind of caching here</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>Regex.<span class="me1">IsMatch</span><span class="br0">&#40;</span>url.<span class="me1">Path</span>, _regexpPaging<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; internalObject = <span class="kw2">null</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; ConvertToInternalInternal<span class="br0">&#40;</span>url, ref internalObject<span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Else, it is ok to use the cached result</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">return</span> base.<span class="me1">ConvertToInternal</span><span class="br0">&#40;</span>url, out internalObject<span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p><br/></p>
<p>The last step is to add our Rewrite module to the web.config:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;providers&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &lt;add
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;name=&quot;MyUrlRewriter&quot;
</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp;enableSimpleAddress=&quot;true&quot;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;friendlyUrlCacheAbsoluteExpiration=&quot;0:0:10&quot;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;type=&quot;Utils.Rewrite, Utils&quot;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp;description=&quot;URL rewriter for paging&quot; /&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &lt;/providers&gt;
</div>
</li>
<li class="li2">
<div class="de2">&lt;/urlRewrite&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p><br/></p>
<p>Now we should be all done! Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/episerver-friendly-urls-for-paginated-pages-and-why-the-asplinkbutton-must-die/510/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Book review: ASP.NET MVC 1.0 &#8211; Test Driven Development</title>
		<link>http://sourcecodebean.com/archives/book-review-asp-net-mvc-1-0-test-driven-development/354</link>
		<comments>http://sourcecodebean.com/archives/book-review-asp-net-mvc-1-0-test-driven-development/354#comments</comments>
		<pubDate>Wed, 09 Dec 2009 09:28:25 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=354</guid>
		<description><![CDATA[About a month ago I finished reading the book ASP.NET MVC 1.0 &#8211; Test Driven Development by Emad Ibrahim. The book weighs in only at about 300 pages, making it easily something you can read in a couple of nights. The book is written in tutorial fashion and is is probably best read with a [...]]]></description>
			<content:encoded><![CDATA[<p>About a month ago I finished reading the book ASP.NET MVC 1.0 &#8211; Test Driven Development by Emad Ibrahim. The book weighs in only at about 300 pages, making it easily something you can read in a couple of nights. The book is written in tutorial fashion and is is probably best read with a laptop running Visual Studio on your lap, so you can follow the examples in the book. The paradigm of the book is Problem, Design, Solution. Emand gudies the reader though the full process of creating a web application in a Test Driven manner. </p>
<p>Besides from only presenting MVC and TTD Emand presents several very useful libraries for Test Driven Development:</p>
<ul>
<li>Moq &#8211; A mocking library for .NET that uses the power of LINQ to create mocks.</li>
<li>Ninject &#8211; Dependency injection library for .NET</li>
<li>MBunit &#8211; An alternative to VSTest</li>
</ul>
<p>I think the book gives a good kickstart in ASP.NET MVC and TTD. My favorite part of the book was actually not reading about MVC itself, it was reading about testing it &#8211; Emad shows the strengths of MVC by showing how it makes testing easier. </p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/book-review-asp-net-mvc-1-0-test-driven-development/354/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rename a Folder using EPiServer.Web.Hosting.UnifiedDirectory</title>
		<link>http://sourcecodebean.com/archives/rename-a-folder-using-episerver-web-hosting-unifieddirectory/304</link>
		<comments>http://sourcecodebean.com/archives/rename-a-folder-using-episerver-web-hosting-unifieddirectory/304#comments</comments>
		<pubDate>Mon, 05 Oct 2009 00:02:47 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[EPiServer]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=304</guid>
		<description><![CDATA[While reading the EPiServer 5 SDK documentation, i found this: Rename a Folder There is no Rename method on the EPiServer.Web.Hosting.UnifiedDirectory class. To rename a folder you need to call the MoveTo method as follows: &#160; protected void RenameFolder&#40;string path, string oldName, string name&#41; &#123; &#160; &#160; if &#40;IsFolder&#40;path&#41;&#41; &#160; &#160; &#123; &#160; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>While reading the EPiServer 5 SDK documentation, i found this:</p>
<blockquote><p><strong>Rename a Folder</strong></p>
<p>There is no Rename method on the EPiServer.Web.Hosting.UnifiedDirectory class. To rename a folder you need to call the MoveTo method as follows:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">protected <span class="kw4">void</span> RenameFolder<span class="br0">&#40;</span><span class="kw4">string</span> path, <span class="kw4">string</span> oldName, <span class="kw4">string</span> name<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>IsFolder<span class="br0">&#40;</span>path<span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; UnifiedDirectory directory = </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; System.<span class="me1">Web</span>.<span class="me1">Hosting</span>.<span class="me1">HostingEnvironment</span>.<span class="me1">VirtualPathProvider</span>.<span class="me1">GetDirectory</span><span class="br0">&#40;</span>path<span class="br0">&#41;</span> as UnifiedDirectory;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw4">int</span> e = <span class="nu0">-1</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span>path.<span class="me1">IndexOf</span><span class="br0">&#40;</span>oldName, ++e<span class="br0">&#41;</span> &gt; <span class="nu0">-1</span><span class="br0">&#41;</span> ;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; StringBuilder sb = new StringBuilder<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; sb.<span class="me1">Append</span><span class="br0">&#40;</span>path.<span class="me1">Substring</span><span class="br0">&#40;</span><span class="nu0">0</span>, e &#8211; <span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; sb.<span class="me1">Append</span><span class="br0">&#40;</span>name<span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; sb.<span class="me1">Append</span><span class="br0">&#40;</span><span class="st0">&quot;/&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; directory.<span class="me1">MoveTo</span><span class="br0">&#40;</span>sb.<span class="me1">ToString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
</blockquote>
<p>What a convenient way of renaming a folder <img src='http://sourcecodebean.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Good thing that you don&#8217;t have to do it too often.</p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/rename-a-folder-using-episerver-web-hosting-unifieddirectory/304/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft Web Platform Installer</title>
		<link>http://sourcecodebean.com/archives/microsoft-web-platform-installer/296</link>
		<comments>http://sourcecodebean.com/archives/microsoft-web-platform-installer/296#comments</comments>
		<pubDate>Sat, 03 Oct 2009 09:51:40 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=296</guid>
		<description><![CDATA[I recently needed to setup a new ASP.NET development environment and deiced to give Microsofts Web Platform Installer 2.0 a chance. I had actually never heard about this product before, but what it does is installing .NET, the needed development libraries, and the express versions of Visual Studio and SQL Server. It required three reboots, [...]]]></description>
			<content:encoded><![CDATA[<p>I recently needed to setup a new ASP.NET development environment and deiced to give Microsofts Web Platform Installer 2.0 a chance. I had actually never heard about this product before, but what it does is installing .NET, the needed development libraries, and the express versions of Visual Studio and SQL Server. It required three reboots, but in total it saved me a lot of time! </p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/microsoft-web-platform-installer/296/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Friendly URLs in ASP.NET using URLRewriter.NET</title>
		<link>http://sourcecodebean.com/archives/friendly-urls-in-aspnet-using-urlrewriternet/243</link>
		<comments>http://sourcecodebean.com/archives/friendly-urls-in-aspnet-using-urlrewriternet/243#comments</comments>
		<pubDate>Mon, 22 Jun 2009 11:28:23 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=243</guid>
		<description><![CDATA[I was having a chat the other day with Danish Peter (yes, another one) about URL rewrites in ASP.NET. In a previous post I wrote about how to use friendly URLs in the Zend framework, in this post, which is based on our discussion, I will discuss how to do this in ASP.NET. Friendly URLs [...]]]></description>
			<content:encoded><![CDATA[<p>I was having a chat the other day with Danish Peter (yes, another one) about URL rewrites in ASP.NET. In a previous post I wrote about how to use friendly URLs in the Zend framework, in this post, which is based on our discussion, I will discuss how to do this in ASP.NET.</p>
<p>Friendly URLs are achieved by a technique called URL-rewrite. A friendly URL is a  URL that is easy to read and understand. Let me give you an example (from a site my girlfriend loves) of what is NOT a friendly URL:</p>
<blockquote><p>http://www.bebe.com/bebe-Jersey-Knit-Apron-Dress/dp/B001UX1NBQ?ie=UTF8&amp;asinSearchPageIndex=13&amp;pf_rd_r=1C6TS27BZZ1CAD6WY81S&amp;navAsinList=B001UNM3XS%2CB001OPYKKQ%2CB001UNNQ52%2CB001RPD88I%<br />
2CB001R4NHHQ%2CB0026BM39W%2CB001QOU6TY%2CB001UX1NNY%2CB001UAA4WI<br />
%2CB0024QP6KM%2CB0026RRN4G%2CB0027DCI6W%2CB001UX3QL6%2CB001UX1NBQ<br />
%2CB001VROPT8%2CB00265NBKS%2CB001RPM80C%2CB001UBWNTO%2CB001RPIC1G<br />
%2CB001PA2NMW&amp;node=675941011&amp;pf_rd_s=search-results&amp;field_browse=675941011&amp;searchSize=20&amp;navAsinListIndex=0&amp;pf_rd_t=101&amp;field_availability=0&amp;id=bebe%20Jersey%20Knit%20Apron%20Dress&amp;searchBinNameList=null&amp;store=core&amp;pf_rd_p=476815091&amp;ref=search_results_14&amp;searchNodeID=675941011&amp;pf_rd_i=675941011&amp;field_launch-date=-1y&amp;searchRank=-custom-rank&amp;searchPage=1&amp;pf_rd_m=A2FMOXN01TSNYY</p></blockquote>
<p>This might be an extreme example, but there are plenty of sites which are as bad. If the above URL was transformed into a friendly URL it might look something like:</p>
<blockquote><p>http://www.bebe.com/Apparel/Dresses/Jersey-Knit-Apron-Dress.html</p></blockquote>
<p>The second address is easier to read. URL rewrite techniques have been around for a long time and the first time I used it was back in the early Apache 1.3 days. Today good sites use friendly URLs and if you have not adopted it yet, you need to start using it.</p>
<p><span id="more-243"></span><br />
There are several benefits from using a friendly url scheme, the most prominent are:</p>
<ol>
<li> 1. The clear structure makes it easier for humans to read and understand the addres</li>
<li> 2. It is easier for search engines to understand what the address is and crawler the site.  URL structure that goes more than three directories deep is not always read by a spider.</li>
<li> 3. If search engines understand the URL, it is also easier for them to help people finding what they want, giving better search results. Hence using keywords and proper titles makes life easier.</li>
</ol>
<p><strong>What options are there for ASP.NET?</strong><br />
There is no built in support for having friendly URLs in ASP.NET, but you could spend your time writing your own URL-rewrite module. Writing your own module is basically spending time reinventing the wheel. If you have the time, go ahead, but if not there are already several good ones out there (free and open source). One that I have found very useful is the URLRewriter.NET (http://urlrewriter.net/). URLRewriter.NET provides similar rewrite capabilities as the mod_rewrite does for Apache.</p>
<p><strong>Using URLRewriter.NET</strong><br />
It is possible to use the URLRewriter.NET module without making any changes to the IIS configuration, this will however limit the functionallity the URLRewriter.NET rewriting capabilities. To use its full power, IIS should be configured to map all requests to the ASP.NET runtime (how to do this is covered in the manual). We will only be touching the surface of URLRewriter.NET so we will not have to do any modifications to the IIS configuration.</p>
<p>To add URLRewriter.NET to your project start out by opening Visual Studio or Visual Web Developer. Open your project and then right click the project in the solution explorer and click on Add Reference, go browse and find the folder you downloaded and unzipped.  You will find the binary (.dll) file in <code>“Loation”\urlrewriternet20rc1b6\UrlRewriterV2\bin\Release</code>.</p>
<p>Before we can use the module we need to make some changes to the web.config. Add the following in the configSections:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;configSections<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;section</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;rewriter&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">requirePermission</span>=<span class="st0">&quot;false&quot;</span> </div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">type</span>=<span class="st0">&quot;Intelligencia.UrlRewriter.Configuration.RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/configSections<span class="re2">&gt;</span></span></span></div>
</li>
</ol>
</div>
<p>This will allow the URL writer to read the rewrite rules we will define later. Now we need to add this module to the httpModules section:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;system</span>.web<span class="re2">&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;httpModules<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;add</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="re0">type</span>=<span class="st0">&quot;Intelligencia.UrlRewriter.RewriterHttpModule, Intelligencia.UrlRewriter&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; <span class="re0">name</span>=<span class="st0">&quot;UrlRewriter&quot;</span> <span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/httpModules<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="sc3"><span class="re1">&lt;/system</span>.web<span class="re2">&gt;</span></span></div>
</li>
</ol>
</div>
<p>By adding the rewriter as a httpModule we allow it to intercept web requests and route the requests to the actual aspx file serving the page. Now we need to define the rewrite rules:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;rewriter<span class="re2">&gt;</span></span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;rewrite</span> <span class="re0">url</span>=<span class="st0">&quot;~/(.+)/(.+)/(.+)/(.+).shtml&quot;</span> <span class="re0">to</span>=<span class="st0">&quot;~/Default.aspx?Year=$1&amp;amp;Month=$2&amp;amp;Date=$3&amp;amp;Title=$4&quot;</span><span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="sc3"><span class="re1">&lt;rewrite</span> <span class="re0">url</span>=<span class="st0">&quot;~/Article/(.+).shtml&quot;</span> <span class="re0">to</span>=<span class="st0">&quot;~/Articles.aspx?ID=$1&quot;</span><span class="re2">/&gt;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="sc3"><span class="re1">&lt;/rewriter<span class="re2">&gt;</span></span></span></div>
</li>
</ol>
</div>
<p>The rewrite rules are defined using regular expressions. Regular expressions are very powerful and is something every programmer should know. The syntax might be hard to remember but there are several great tools to help build advanced regular expressions, for example the RegexDesigner.NET (http://www.sellsbrothers.com/tools/#regexd) that Chris Sells has created.</p>
<p>The above rewrite rules are simple. The first rewrite rule will rewrite URLs like<br />
<blockquote>sourcecodebean.com/2009/04/01/1.shtml</p></blockquote>
<p> to </p>
<blockquote><p>sourcecodebean.com/Default.aspx?Year=2009&#038;Month=04&#038;Date=01&#038;Id=1</p></blockquote>
<p><br/><br />
And the second rewrite rule will match requests starting with ~/Article/ so it will rewrite URLs like<br />
<blockquote>sourcecodebean.com/Article/1.shtml</p></blockquote>
<p> to<br />
<blockquote>sourcecodebean.com/Articles.aspx?ID=1</p></blockquote>
<p><strong>Finishing up</strong><br />
By now you hopefully have a functioning site that uses friendly URLs. One of the common problems you might run into is broken links. To avoid this you should make sure that you reference all your pages from the root level (~) and that all your links has the runat=server tag.</p>
<p>Thanks for your input Peter!  You can check out his Danish Peter blog over at <a href="http://www.magic-mouse.dk">Magic Mouse</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/friendly-urls-in-aspnet-using-urlrewriternet/243/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Clearing a form in ASP.NET</title>
		<link>http://sourcecodebean.com/archives/clearing-a-form-in-aspnet/194</link>
		<comments>http://sourcecodebean.com/archives/clearing-a-form-in-aspnet/194#comments</comments>
		<pubDate>Fri, 15 May 2009 15:59:53 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=194</guid>
		<description><![CDATA[You would think that ASP.NET would have build in support for something so simple as clearing all input fields on a page, but no. However, this easy to add. Add the following to your Page_Load (btnClear should be the name of your clear button): btnClear.Attributes.Add("onClick", "document.forms[0].reset();return false;");]]></description>
			<content:encoded><![CDATA[<p>You would think that ASP.NET would have build in support for something so simple as clearing all input fields on a page, but no. However, this easy to add. Add the following to your Page_Load (btnClear should be the name of your clear button):</p>
<p><code lang="c#"><br />
btnClear.Attributes.Add("onClick", "document.forms[0].reset();return false;");<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/clearing-a-form-in-aspnet/194/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: sourcecodebean.com @ 2012-05-30 05:53:14 -->
