<?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>giving you tricks and tips of good coding</description>
	<lastBuildDate>Sun, 06 Jun 2010 16:40:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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,  [...]]]></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>3</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. 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>1</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; &#160; UnifiedDirectory directory = 


&#160; &#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 are [...]]]></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>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>7</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>
		<item>
		<title>An update on the mono memory issue</title>
		<link>http://sourcecodebean.com/archives/an-update-on-the-mono-memory-issue/184</link>
		<comments>http://sourcecodebean.com/archives/an-update-on-the-mono-memory-issue/184#comments</comments>
		<pubDate>Wed, 13 May 2009 13:21:16 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mono]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=184</guid>
		<description><![CDATA[The workaround I tested a few weeks ago did not really solve my problem – actually it made it worse. The autorestart caused mono to hang and not restart at all, so my site stopped responding every 6th hour. I quickly had to disable this. Still I had the memory consumption problems. From various sources [...]]]></description>
			<content:encoded><![CDATA[<p>The workaround I tested a <a href="http://sourcecodebean.com/archives/mod-mono-server2-memory-consumption-problems">few weeks ago</a> did not really solve my problem – actually it made it worse. The autorestart caused mono to hang and not restart at all, so my site stopped responding every 6th hour. I quickly had to disable this. Still I had the memory consumption problems. From various sources I was told that the memory issues would be fixed in the recently released mono 2.4. Also I found a <a href="https://bugzilla.novell.com/show_bug.cgi?id=472732">bug report</a> regarding AutoRestart, which also should have been fixed in 2.4. So I decided to give Mono 2.4 a try.<br />
The problem was that there were no packages for Ubuntu 8.10, so I had to download the sources and build my own deb packages. I found this great <a href="http://go-mono.com/forums/#nabble-p22841086">blog post</a> that describes the process of building and installing Mono 2.4. </p>
<p>So far it seems to be working, but it is too early to say if the memory consumption issues are resolved. </p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/an-update-on-the-mono-memory-issue/184/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>mod-mono-server2 memory consumption problems</title>
		<link>http://sourcecodebean.com/archives/mod-mono-server2-memory-consumption-problems/121</link>
		<comments>http://sourcecodebean.com/archives/mod-mono-server2-memory-consumption-problems/121#comments</comments>
		<pubDate>Tue, 31 Mar 2009 21:21:49 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mono]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=121</guid>
		<description><![CDATA[Lately I have been experiencing that the mod-mono-server2 process running on the server hosting the video upload web-service (I blogged about this in my last post) has been consuming a lot of memory. Once, it even reached the point where all memory (1.5GB) of the server was consumed and the Linux OOM-killer killed the mod-mono-server2 [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I have been experiencing that the mod-mono-server2 process running on the server hosting the video upload web-service (I blogged about this in my last post) has been consuming a lot of memory. Once, it even reached the point where all memory (1.5GB) of the server was consumed and the Linux OOM-killer killed the mod-mono-server2 process. At this point apache failed to restart it. If you are interested you can see the kernel log <a href='http://sourcecodebean.com/wp-content/uploads/2009/03/kern.log'>here</a> and the apache log <a href='http://sourcecodebean.com/wp-content/uploads/2009/03/apache.log'>here</a>. The mono version I am using is mono-apache-server2 1.9.1-2 (Ubuntu 8.10 Intrepid).</p>
<p>I googled the issue and found some information on the <a href="http://www.mono-project.com/Mod_mono">mod_mono</a> page:</p>
<blockquote><p><strong>Under high load, mono process consumes a lot of memory, website stops responding</strong><br />
These symptoms have been reported, but their underlying causes are not known. Set the MonoAutoRestartMode, MonoAutoRestartRequests, MonoMaxActiveRequests, and MonoMaxWaitingRequests directives as described earlier to limit the lifetime of the mono process and to restrict the concurrency happening in the server. </p></blockquote>
<p>The above describes my issue pretty well, except for the &#8220;under high load&#8221; part. The video transcoding service is still in beta and is only used by one customer so far. It serves around 500 requests a day, which is not a lot, so I wouldn&#8217;t expect this kind of behavior. My guess is that every time a file is uploaded using the UploadFile webmethod additional memory is allocated, but not properly released/reused by mono. </p>
<p><del datetime="2009-05-13T13:26:11+00:00">As a workaround for this I will have the mod-mono-server2 process restart restart every 6th hour. This can be done by adding the following lines to <code>/etc/apache2/mods-enabled/mod_mono.conf</code>:</del> Update: This did not work, caused my site to hang entirely every 6th hour. </p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">MonoAutoRestartMode <a href="http://www.php.net/time"><span class="kw3">Time</span></a></div>
</li>
<li class="li1">
<div class="de1">MonoAutoRestartRequests <span class="nu0">00</span>:<span class="nu0">06</span></div>
</li>
</ol>
</div>
<p>Hopefully this will limit the memory usage, for now. I would appreciate feedback from anyone who have experienced similar problems on mono. </p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/mod-mono-server2-memory-consumption-problems/121/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Building a distributed web service using Amazon Web Services</title>
		<link>http://sourcecodebean.com/archives/building-a-distributed-web-service-using-amazon-web-services/93</link>
		<comments>http://sourcecodebean.com/archives/building-a-distributed-web-service-using-amazon-web-services/93#comments</comments>
		<pubDate>Sun, 22 Mar 2009 18:18:08 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://sourcecodebean.com/?p=93</guid>
		<description><![CDATA[A few months ago my employer asked me if it would be possible to create a web service for encoding videos. I had been playing around with Amazon&#8217;s web services for a while, and it seemed like the perfect foundation for building this.
I decided to build the backend in Python and use ffmpeg for encoding [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago my employer asked me if it would be possible to create a web service for encoding videos. I had been playing around with Amazon&#8217;s web services for a while, and it seemed like the perfect foundation for building this.</p>
<p>I decided to build the backend in Python and use ffmpeg for encoding movies. I looked into building the web service frontend in Python as well, but the SOAP libraries I could find for Python did not seem very mature or maintained. Instead I started thinking about building it in ASP.NET (I had previous experiences from building web services in ASP.NET). After some research and testing with Apache and Mono (I wanted to use Linux VMs only) I decided to develop the frontend in ASP.NET but host it on Apache.</p>
<p>To make the service scalable I decided to break it down into several parts and use message passing between the different parts. The parts I broke it down into are:</p>
<ul>
<li>Web service frontend – what the user calls to encode a movie. Implemented in ASP.NET, hosted on Apache/Mono on Linux.</li>
<li>Encode Worker – A python process managing the encoding of videos.</li>
<li>Encode Master – Manages number of running Encode Workers. Implemented in Python.</li>
</ul>
<p>When a movie gets uploaded to the web service frontend it gets placed into the encode queue. The encode workers periodically checks if there is anything in the queue, and if it is encodes it. The Encode Master manages the number of running Encode Workers (based on the current length of the encode queue). If the queue growes to long, we just fire up a few new VMs running the worker. </p>
<p> This is a schematic view of how the service has been implemented and how the different components are related to the Amazon services:</p>
<p><img class="size-large wp-image-92" title="Video Encoding Service" src="http://sourcecodebean.com/wp-content/uploads/2009/03/dqcvideo-1024x535.png" alt="Video Encoding Service" width="650" /></p>
<p>Right now we are implementing the solution for our first customer, pretty existing I must say! In an upcoming post I will discuss the different libraries for Python and ASP.NET I used for communicating with the Amazon Web Services.</p>
]]></content:encoded>
			<wfw:commentRss>http://sourcecodebean.com/archives/building-a-distributed-web-service-using-amazon-web-services/93/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
