<?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>Meadows Design &#187; Development</title>
	<atom:link href="http://meadowsdesign.com/blog/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://meadowsdesign.com/blog</link>
	<description>News, Notes and Nothings from a Custom Solution Provider</description>
	<lastBuildDate>Sat, 29 Aug 2009 13:22:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Coding Smarter &#8211; Understand Your Medium</title>
		<link>http://meadowsdesign.com/blog/2009/08/12/code-smarter-understand-your-medium/</link>
		<comments>http://meadowsdesign.com/blog/2009/08/12/code-smarter-understand-your-medium/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 18:05:54 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Coding Smarter]]></category>

		<guid isPermaLink="false">http://meadowsdesign.com/blog/?p=46</guid>
		<description><![CDATA[There has been a lot of chatter lately about good design practices.  I don&#8217;t know if this is because I&#8217;ve just noticed it more, if it&#8217;s part of the alt.net push on the community, or if there are actually more people interested in improving our craft.  
Several sites exist out there that urge [...]]]></description>
			<content:encoded><![CDATA[<p>There has been a lot of chatter lately about good design practices.  I don&#8217;t know if this is because I&#8217;ve just noticed it more, if it&#8217;s part of the alt.net push on the community, or if there are actually more people interested in improving our craft.  </p>
<p>Several sites exist out there that urge developers to think about what they&#8217;re doing and they range from the architectural perspective (<a href="http://www.codebetter.com">codebetter.com</a>) to the human factors perspective (<a href="http://www.codinghorror.com">codinghorror.com</a> &#8212; an excellent site that never disappoints.)</p>
<p>Regardless of the reason, it appears to me that a fundamental piece of the puzzle is missing.  That piece being coding better isn&#8217;t the same thing as coding smarter.  It appears to me that some developers have a unique form of <a href="http://en.wikipedia.org/wiki/Savant_syndrome">savant syndrome</a> granting them all the architectural prowess for which one could ever hope but none of the common sense development practices that can actually make or break an application.</p>
<div align="center"><img src="/blog/images/rainman.jpg" alt="I'm an excellent developer." /><br />
I&#8217;m an excellent developer.<br />&nbsp;
</div>
<p>Let&#8217;s take the following scenario that, sadly, is one of four from an application I inherited.</p>
<p>The first scenario in &#8220;Coding Smarter&#8221; involves understanding your medium.  By that, I mean that you should really understand how the technology you&#8217;re using functions.  </p>
<p>This application wanted to maintain a user id once the user was logged in.  I wrote about an <a href="http://stackoverflow.com/questions/1263580/persisting-caching-data-between-requests-common-approach/1264062">expansion of this method on Stackoverflow</a>.  </p>
<p>The general idea is that you want to maintain as little (or as much, sadly) state as you can between requests and given that <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol">HTTP is a stateless protocol</a> you need to store it somewhere.  Typically this information is stored in the session on the server but the authors of the application didn&#8217;t deem the session worthy and decided that they would store the user id of the user making the request in&#8230; wait for it&#8230; the ViewState.</p>
<div align="center">
<img src="/blog/images/facepalm.jpg" alt="Facepalm - because expressing how dumb this is in words is impossible." /><br />&nbsp;
</div>
<p>Think about this for a second.  What do we know about the ViewState?</p>
<p>Well, for starters, the ViewState is sent back and forth between the server and the client.  This means that for every item that is stored in the ViewState, that item must be <a href="http://msdn.microsoft.com/en-us/library/ms972976.aspx#viewstate_topic8">returned from the client to the server with every request</a>. (Incidentally, they also made liberal use of UpdatePanel).  This might be &#8220;OK&#8221; &#8212; not really, but wait for it &#8212; because the user id is only an integer, but this application stored EVERYTHING in the ViewState that it needed.  No use of session variables were involved.  </p>
<p>The BIGGER issue with storing the user id in the ViewState is that it is not secure.  ViewState is not encrypted by default, <a href="http://msdn.microsoft.com/en-us/library/ms972976.aspx#viewstate_topic12">merely encoded</a>.  Not surprisingly, there was no encrypting of the ViewState taking place in the code so anyone that could access it could decode it.  </p>
<p>In the developer&#8217;s defense, they did encrypt the individual fields that were going into the ViewState, but unless they were <a href="http://www.codeproject.com/KB/security/SimpleEncryption.aspx">encrypting them properly</a> they may as well not have encrypted them at all.</p>
<p>The BIGGEST problem is that there is, essentially, no user  authentication timeout.  That means that the user can be using the site, step away from the computer for a week, a month, even a year, and then come back and continue on their merry way on the site.  Or, go about browsing other sites, hit back in their browser to load a page from the site (there was also no client-side cache expiration), perform some new action and automatically be logged into the site.  This <em>might</em> be fine on a site that&#8217;s not handling sensitive information.  Unfortunately, this site is.</p>
<p>The lesson is that just because a framework or platform makes something available to you doesn&#8217;t mean that you have to use it.  If you want to use it, make sure you understand what it is, how it functions, and what the repercussions of using it actually are.</p>
<p>I&#8217;m debating on turning this into a series given the number of issues I typically stumble upon when inheriting projects.  If you would like to see more of this, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://meadowsdesign.com/blog/2009/08/12/code-smarter-understand-your-medium/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New MVC Tutorials Posted</title>
		<link>http://meadowsdesign.com/blog/2009/02/26/new-mvc-tutorials-posted/</link>
		<comments>http://meadowsdesign.com/blog/2009/02/26/new-mvc-tutorials-posted/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 16:34:33 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://meadowsdesign.com/blog/?p=25</guid>
		<description><![CDATA[Steven Walther has posted a new set of MVC tutorials @ http://www.asp.net/learn/mvc/#MVC_SampleApp that are almost full-lifecycle.  Might be worth a read.
]]></description>
			<content:encoded><![CDATA[<p>Steven Walther has posted a new set of MVC tutorials @ <a href="http://www.asp.net/learn/mvc/#MVC_SampleApp">http://www.asp.net/learn/mvc/#MVC_SampleApp</a> that are almost full-lifecycle.  Might be worth a read.</p>
]]></content:encoded>
			<wfw:commentRss>http://meadowsdesign.com/blog/2009/02/26/new-mvc-tutorials-posted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WSS 3.0 (MOSS/SharePoint), Site Collections, and Server.MapPath</title>
		<link>http://meadowsdesign.com/blog/2007/11/15/wss-30-mosssharepoint-site-collections-and-servermappath/</link>
		<comments>http://meadowsdesign.com/blog/2007/11/15/wss-30-mosssharepoint-site-collections-and-servermappath/#comments</comments>
		<pubDate>Thu, 15 Nov 2007 21:26:25 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Commerce Server]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://meadowsdesign.com/blog/?p=15</guid>
		<description><![CDATA[One of my current projects is a Commerce Server/MOSS 2007 integration project.Â  I had the need to know where to store the configuration of a sub-site within a site collection of the main web application.
For those of you familiar with ASP.NET 2.0, you know that if you want to find the root of the application, [...]]]></description>
			<content:encoded><![CDATA[<p>One of my current projects is a Commerce Server/MOSS 2007 integration project.Â  I had the need to know where to store the configuration of a sub-site within a site collection of the main web application.</p>
<p>For those of you familiar with ASP.NET 2.0, you know that if you want to find the root of the application, you use Server.MapPath.Â  Turns out the the root directory (~/) and the bin directory (~/bin &#8212; typically) are the same as the parent site.Â  This means that if your sub-site needs to read information from the web.config then you can store it in the web.config of the parent application.</p>
<p>There is one downside to this.Â  If you have multiple instances of the same site definition within the same web application, there is no way to separate values within the web.config.Â  As an example, assume you need to email an administrator when a site experiences a problem but the administrator is different for each subsite.Â  This information cannot be stored in the web.config as both subsites in the site collection will share the configuration.</p>
<p>This may not be news to some, but without years of SharePoint/WSS experience I found this important to share.</p>
]]></content:encoded>
			<wfw:commentRss>http://meadowsdesign.com/blog/2007/11/15/wss-30-mosssharepoint-site-collections-and-servermappath/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASP.NET, WebResource.axd, and Reverse Proxies</title>
		<link>http://meadowsdesign.com/blog/2007/10/23/aspnet-webresourceaxd-and-reverse-proxies/</link>
		<comments>http://meadowsdesign.com/blog/2007/10/23/aspnet-webresourceaxd-and-reverse-proxies/#comments</comments>
		<pubDate>Wed, 24 Oct 2007 02:56:07 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://meadowsdesign.com/blog/?p=6</guid>
		<description><![CDATA[Sometimes it&#8217;s necessary to host applications behind a reverse proxy.  While the application may appear locally as http://somehost.com/someapp, the outside world would see the application as http://somecompany.com/ &#8212; so this is the opposite of the typical scenario, but the premise is the same.  This is all fine and good and is easy enough [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes it&#8217;s necessary to host applications behind a reverse proxy.  While the application may appear locally as http://somehost.com/someapp, the outside world would see the application as http://somecompany.com/ &#8212; so this is the opposite of the typical scenario, but the premise is the same.  This is all fine and good and is easy enough to setup with Apache in the front end on the cheap.</p>
<p>The problem occurs with how ASP.NET tells the client to retrieve <a title="Working with Web Resources in ASP.NET 2.0" href="http://support.microsoft.com/kb/910442">embedded resources</a>.  Embedded resources are typically returned to the web client by a call to WebResource.axd that exists in the application root (~/) &#8212; the file&#8217;s not actually there, it&#8217;s a handler.  From the ASP.NET application&#8217;s perspective, ~/ maps to /someapp.  However, the web client is assuming that the application root is / because they&#8217;re looking at the pages through the reverse proxy, a proxy of which ASP.NET is blissfully unaware.</p>
<p>As stated earlier, the true application root is /someapp and ASP.NET tells the client to access WebResource.axd at /someapp/WebResource.axd.  The web client assumes that this is appended to the current root which is http://somecompany.com/ and then tries to retrieve WebResource.axd at http://somecompany.com/someapp/WebResource.axd, a location that the proxy then maps to http://somehost.com/someapp/someapp/WebResource.axd.  This isn&#8217;t accounted for in the http handler&#8217;s mapping and the request returns a 404.</p>
<p>The 404 File Not Found code is problematic in that WebResource.axd is the handler responsible for returning all of the embedded resources in the application &#8212; typically JavaScript for ASP.NET user controls, ASP.NET validation controls, and 3rd party controls.  The application breaks and it&#8217;s bad times for all.  Enter <a title="UrlRewritingNet.UrlRewrite" href="http://www.urlrewriting.net/en/Default.aspx">UrlRewritingNet.UrlRewrite.</a></p>
<p>This free open source library will allow rewrites to be performed simply by adding a couple entries in the application&#8217;s web.config and including the library in the application&#8217;s bin folder.  This is perfect for shared hosting environments where access to the actual server to install isapi rewrite is not possible.</p>
<p>The <a title="URLRewritingNet.UrlRewrite PDF Documentation" href="http://www.urlrewriting.net/download/UrlRewritingNet20.English.pdf">documentation </a>is pretty clear, though the English is a bit broken, and contains the enumerated steps for installation into the application.  Once the library has been installed, all that&#8217;s left is to write some simple rewrite rules.</p>
<p>Inside the web.config, for this application, we would add the following rewrite rules</p>
<pre class="brush: xml;">
&lt;urlrewritingnet xmlns=&quot;http://www.urlrewriting.net/schemas/config/2006/07&quot; &gt;
&lt;rewrites&gt;
&lt;add name=&quot;WebResourceFix&quot; virtualUrl=&quot;^~/WebResource.axd(.*)&quot; rewriteUrlParameter=&quot;IncludeQueryStringForRewrite&quot; destinationUrl=&quot;~/WebResource.axd$1&quot; ignoreCase=&quot;true&quot;/&gt;
&lt;add name=&quot;ScriptResource&quot; virtualUrl=&quot;^~/(.*)/ScriptResource.axd(.*)&quot; rewriteUrlParameter=&quot;IncludeQueryStringForRewrite&quot; destinationUrl=&quot;~/ScriptResource.axd$2&quot; ignoreCase=&quot;true&quot;/&gt;
&lt;add name=&quot;ReplaceRoot&quot; virtualUrl=&quot;^~/(.*)/(.*)&quot; rewriteUrlParameter=&quot;IncludeQueryStringForRewrite&quot; destinationUrl=&quot;~/$2&quot; ignoreCase=&quot;true&quot;/&gt;
&lt;/rewrites&gt;
&lt;/urlrewritingnet&gt;
</pre>
<p>This rewrite rule will take any inbound request to /someapp/WebResource.axd and map it to /WebResource.axd.  This ends the 404 and its good times for all.</p>
<p>So far, I&#8217;ve had nothing but success with this approach and have extended it to handle the ASP.NET Ajax resource tool ScriptResource.axd that suffers from the same fate.  Additionally, if Web Service callbacks are used in the application for Ajax invocation, the same rules will need to be applied to the page and it may be easier to simply remap anything that comes in for /someapp to /.<br />
Note, there are <a title="other methods" href="http://forums.asp.net/t/1167408.aspx">other methods</a> that will allow you to fix some of these issues, but they&#8217;re not always achievable in shared hosting environments or in environments where configuration is tightly controlled.   Further, this does not handle problems with using web.sitemap in an application that is behind a reverse proxy but that will be left as an exercise to the reader.</p>
]]></content:encoded>
			<wfw:commentRss>http://meadowsdesign.com/blog/2007/10/23/aspnet-webresourceaxd-and-reverse-proxies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
