<?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>PHP vs .Net &#187; REST</title>
	<atom:link href="http://www.phpvs.net/category/rest/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phpvs.net</link>
	<description>ASP.Net and PHP go head to head</description>
	<lastBuildDate>Sat, 24 Dec 2011 18:20:11 +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>HTTP Signed Requests with PHP</title>
		<link>http://www.phpvs.net/2011/12/24/http-signed-requests-with-php/</link>
		<comments>http://www.phpvs.net/2011/12/24/http-signed-requests-with-php/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 18:19:27 +0000</pubDate>
		<dc:creator>blake</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/?p=268</guid>
		<description><![CDATA[I thought I'd write a quick primer on a basic implementation of HTTP request signing with PHP. I see a lot of posts dealing with the topic, especially by people writing homebrew REST services. What are signed HTTP requests? Signed HTTP requests are simply a normal HTTP request, such as a GET or a POST, [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I'd write a quick primer on a basic implementation of HTTP request signing with PHP. I see a lot of posts dealing with the topic, especially by people writing homebrew REST services.</p>
<p><a href="http://www.phpvs.net/wp-content/uploads/2011/12/digitalsecurity.jpg"><img src="http://www.phpvs.net/wp-content/uploads/2011/12/digitalsecurity.jpg" alt="" title="Digital Fingerprint" width="353" height="281" class="aligncenter size-full wp-image-288" /></a></p>
<h2>What are signed HTTP requests?</h2>
<p>Signed HTTP requests are simply a normal HTTP request, such as a GET or a POST, that happens to include a signature as part of the request.  A signature is just a string of characters generated in a meaningful way.  This signature can be used by the receiving party (ie. a REST service) to validate the request and ensure that it hasn't been tampered with.</p>
<h4>What are signed requests good for?</h4>
<p>In a nutshell, validating an HTTP request where restricted access to resources are necessary. For example, a service that allows someone to update their personal information needs to ensure that people can only update <em>their own</em> personal information. Signed requests ensure that the service that receives the data can verify that the sender is who they claim they are (or at least possesses the proper secret key, a de-facto assumption it is the right person).</p>
<p>Obviously, having someone log in and create a session is another method of verifying user identity, however, this is not always efficient or possible, especially with web services. As an example, every Facebook application developer gets a secret key when they create an application on Facebook. When Facebook sends information to someone's application, it will include a signed request that is only valid with that developer's key.  By checking the signature, a developer can verify that a request came from Facebook, and isn't someone trying to fool their application.  They also don't need to provide a complicated session procedure or have Facebook "log in" to their application; the signed request is enough.</p>
<h4> What <em>aren't</em> signed requests good for?</h4>
<p>Signed requests are not a form of encryption. If the data being sent is sensitive in nature, such that you wouldn't want it being sniffed in transit over a network connection, then SSL encrypted communication (HTTPS) is the way to go. For simple REST services however, often you just need to limit requests based on a user or other similar scope, and signed requests are sufficient for that.</p>
<h2>A problem that signed requests can solve</h2>
<p>Here is an example situation that has a security problem that can be solved by the use of signed requests. Let's say you operate a network of beer brewing web sites, and the brewers are allowed to send updates via a REST service you have provided. Each brewer has their own user id that they get when they sign up to your service. <strong>Bob's Brewery</strong> (user id <strong>1234</strong>) wants to update their email address. The simplest of implementations might allow for a request to be sent like this: <code>/user/update?email=newbob@example.com&amp;userid=1234</code>. However, if this was the only thing the REST service needed to update an email address, it would be trivial to cause serious mayhem. For example, <strong>Mr. Evil's Brewery</strong> could send in a simple request to change Bob's email address, just by finding Bob's ID somewhere, or even trying random ones:</p>
<p><code>/user/update?email=evil@example.org&amp;userid=1<br />
/user/update?email=evil@example.org&amp;userid=12<br />
/user/update?email=evil@example.org&amp;userid=1234<br />
etc.</code></p>
<p>Too easy! Obviously more security is needed, and this is where the concept of secret keys comes in.</p>
<h2>Secret Keys</h2>
<p>It is a common practice to assign each user a secret key that they use to interact with a web service, often called an API key, generally consisting of randomly generated characters. In this case, you could give Bob a secret key when he signs up with the brewery network, and it would be stored in your database along with the rest of his account information.</p>
<p>Here's where I often see confusion setting in. Many people think it is logical that the secret key be <strong><em>sent</em></strong> as part of the API request, because after all, it uniquely identifies the user and it was given only to that particular person. <strong>However, this is a security problem!</strong></p>
<p>The thing about secret keys is that they have to remain secret, just like any password. As soon as a key is leaked, whoever finds it can impersonate that account, just as easily as Mr. Evil's Brewery did in the previous example. <strong>If you send a secret key as part of an HTTP request, it is no longer secret.</strong> You have just leaked it to whoever cared to be listening! A network sniffer could pick it up, or it could be recorded in proxy logs or web server logs that aren't secured. Perhaps your ISP is doing deep packet inspection, and a rogue employee makes off with the logs. Who knows!</p>
<p>The following is an example of this type of insecurity. Bob is sending his update request along with the secret key:</p>
<p><code>/user/update?email=newbob@example.com&amp;userid=1234&amp;secret_key=bobs-super-secret-key</code></p>
<p>Now, pretend that Bob goes to his local Tarborks coffee shop and jumps on the free open wireless connection. Mr. Evil happens to be there, and fires up his network sniffer program and starts watching all the HTTP traffic on the network. He sees Bob's request go out, since HTTP connections are not secure. Now he has Bob's secret key, and can make any kind of request he wants with it. Maybe he could even delete Bob's account with a request to <code>/user/delete?userid=1234&amp;secret_key=bobs-super-secret-key</code>, or send insults to Bob's customers using a mail endpoint!</p>
<p><strong>Sending the secret key as part of a network request is NOT safe.</strong> So how do we properly identify the sender if the user id can't be trusted and they can't send us their key? Well, you knew I'd get to it eventually... signed requests!</p>
<h2>Signed HTTP Requests</h2>
<p>To produce a signed HTTP request, the sender and the receiver must both know the rules on how to generate a signature. It can be any crazy method you care to dream up, but a common one is as follows:</p>
<ol>
<li>The sender organizes the data they want to send in a logical way, such as sorting it alphabetically.</li>
<li>The data is run through a hashing algorithm using the secret key to produce a <strong>hash</strong>. Hashing algorithms produce short strings of characters that vary based on the input data, and the output is sufficiently unique such that varying the input data by even one character produces a completely different hash.</li>
<li>The hash is added to the original data and sent.</li>
<li>The receiver identifies the user and gets the secret key from their associated account information, and recreates the hash on the received data.</li>
<li>If the recreated hash matches the one included in the request, the request is valid.</li>
</ol>
<p>To return to our Tarborks coffee shop scenario, the request going out might look like this now:</p>
<p><code>/user/update?email=newbob@example.com&amp;userid=1234&amp;sig=x1zz645</code></p>
<p>If Mr. Evil sniffs this request, he might be pretty pleased with himself and try to change it to <code>/user/update?email=evil@example.org&amp;userid=1234&amp;sig=x1zz645</code>. This request would be rejected by the server however, since the <em>signature is now invalid</em>! When Mr. Evil changed the request, he needed to change the signature to match. But since he doesn't have Bob's secret key, he can't generate a correct signature, for this request or any other he cares to make up.  The only valid request he can possibly make is the exact same one he just sniffed, and that's not very malicious at all, since it's what Bob was trying to do anyway.</p>
<h4>Get to the code already</h4>
<p>Assuming Bob's user id is 1234, and the secret key you gave him is "bobs-super-secret-key", he might write the following PHP code.</p>
<h3>User code</h3>
<div class="igBar"><span id="lphp-5"><a href="#" onclick="javascript:showPlainTxt('php-5'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-5">
<div>
<ol>
<li>
<div><span style="color:#0000FF;">$USER_ID</span> = <span style="color:#FF0000;">"1234"</span>;</div>
</li>
<li>
<div><span style="color:#0000FF;">$SECRET_KEY</span> = <span style="color:#FF0000;">"bobs-super-secret-key"</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#008000;">/**</span></div>
</li>
<li>
<div><span style="color:#008000;"> * @param array $data Array of key/value pairs of data</span></div>
</li>
<li>
<div><span style="color:#008000;"> * @param string $secretKey</span></div>
</li>
<li>
<div><span style="color:#008000;"> * @return string A generated signature for the $data based on $secretKey</span></div>
</li>
<li>
<div><span style="color:#008000;"> */</span></div>
</li>
<li>
<div><span style="color:#000000; font-weight:bold;">function</span> generateSignature<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span>,<span style="color:#0000FF;">$secretKey</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//sort data array alphabetically by key</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <a href="http://www.php.net/ksort"><span style="color:#000066;">ksort</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//combine keys and values into one long string</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#0000FF;">$dataString</span> = <span style="color:#FF0000;">''</span>;</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#616100;">foreach</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span> <span style="color:#616100;">as</span> <span style="color:#0000FF;">$key</span> =&gt; <span style="color:#0000FF;">$value</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$dataString</span> .= <span style="color:#0000FF;">$key</span>.<span style="color:#0000FF;">$value</span>;</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//lowercase everything</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#0000FF;">$dataString</span> = <a href="http://www.php.net/strtolower"><span style="color:#000066;">strtolower</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$dataString</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//generate signature using the SHA256 hashing algorithm</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#616100;">return</span> hash_hmac<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"sha256"</span>,<span style="color:#0000FF;">$dataString</span>,<span style="color:#0000FF;">$secretKey</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#0000FF;">$bobsData</span> = <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF0000;">"userid"</span> =&gt; <span style="color:#0000FF;">$USER_ID</span>,</div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF0000;">"email"</span> =&gt; <span style="color:#FF0000;">"newbob@example.com"</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#0000FF;">$sig</span> = generateSignature<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$bobsData</span>,<span style="color:#0000FF;">$SECRET_KEY</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//add signature to the outgoing data</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$bobsData</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'sig'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF;">$sig</span>;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//generate HTTP query string</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$queryString</span> = http_build_query<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$bobsData</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$queryString</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The code above outputs <code>userid=1234&amp;email=newbob%40example.com&amp;sig=efffd9cc30a220f2981b5124e1caa44d91b85aa2d2181f5331f48ca719983c1d</code>.  That's the HTTP query string that Bob would send to the <code>/user/update</code> endpoint to change his email address.  So how does the service verify the request?</p>
<h3>Server-side code</h3>
<div class="igBar"><span id="lphp-6"><a href="#" onclick="javascript:showPlainTxt('php-6'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-6">
<div>
<ol>
<li>
<div><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/empty"><span style="color:#000066;">empty</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_REQUEST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'userid'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; throw <span style="color:#000000; font-weight:bold;">new</span> Exception<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"No user id was sent with the request."</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//look up the account associated with the value in $_REQUEST['userid']</span></div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//and get the secret key for that account - implement as necessary</span></div>
</li>
<li>
<div><span style="color:#0000FF;">$secretKey</span> = getSecretKeyFromUserId<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_REQUEST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'userid'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#0000FF;">$data</span> = <span style="color:#0000FF;">$_REQUEST</span>;</div>
</li>
<li>
<div><span style="color:#0000FF;">$receivedSignature</span> = <span style="color:#0000FF;">$data</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'sig'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//generate a signature using the data sent by the user, without the 'sig'</span></div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//parameter of course. Note that the generateSignature() function is the</span></div>
</li>
<li>
<div><span style="color:#FF9933; font-style:italic;">//SAME ONE that the users would use!</span></div>
</li>
<li>
<div><a href="http://www.php.net/unset"><span style="color:#000066;">unset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'sig'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#0000FF;">$generatedSignature</span> = generateSignature<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$data</span>,<span style="color:#0000FF;">$secretKey</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div>&nbsp;</div>
</li>
<li>
<div><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$generatedSignature</span> != <span style="color:#0000FF;">$receivedSignature</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; throw <span style="color:#000000; font-weight:bold;">new</span> Exception<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"Received signature is invalid!"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li>
<div><span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li>
<div>&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">//continue on, knowing it is the right user making the request.</span></div>
</li>
<li>
<div><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>There you have it. Signed requests!</p>
<h4>Advanced Usage</h4>
<p>The signature for a signed request can be sent in different ways. Some services, such as <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html">Amazon's S3 REST API</a>, puts the signature in the HTTP headers. This is arguably a bit cleaner than including it in the parameters of an HTTP request, since the signature doesn't get mixed in with the data, and has implications for caching as well (browser caches and proxies). If you want to do it that way, you might have the user set a header as part of their HTTP request:</p>
<div class="igBar"><span id="lphp-7"><a href="#" onclick="javascript:showPlainTxt('php-7'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-7">
<div>
<ol>
<li>
<div><a href="http://www.php.net/header"><span style="color:#000066;">header</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"X-Brewery-Sig: "</span>.<span style="color:#0000FF;">$sig</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>And the receiving server, instead of looking for the sig parameter in <code>$_REQUEST['sig']</code> (and having to remove it before running the data through the generator function), would find it in:</p>
<div class="igBar"><span id="lphp-8"><a href="#" onclick="javascript:showPlainTxt('php-8'); return false;">&gt;&gt; show as plain text</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-8">
<div>
<ol>
<li>
<div><span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'HTTP_X_BREWERY_SIG'</span><span style="color:#006600; font-weight:bold;">&#93;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Hope you found this useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2011/12/24/http-signed-requests-with-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ASP.Net Web Forms dying a slow death?</title>
		<link>http://www.phpvs.net/2008/04/25/aspnet-web-forms-dying-a-slow-death/</link>
		<comments>http://www.phpvs.net/2008/04/25/aspnet-web-forms-dying-a-slow-death/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 02:02:11 +0000</pubDate>
		<dc:creator>morgan</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://www.phpvs.net/2008/04/25/aspnet-web-forms-dying-a-slow-death/</guid>
		<description><![CDATA[Being a web programmer for the last 10 years, I've seen a few different paradigms come and go in the web world. Looking around today, I can't help but think that the writings are on the wall for the ASP.Net "webforms" web application model. When it debuted, it was revolutionary to have a fully typed, [...]]]></description>
			<content:encoded><![CDATA[<p>Being a web programmer for the last 10 years, I've seen a few different paradigms come and go in the web world.  Looking around today, I can't help but think that the writings are on the wall for the ASP.Net "webforms" web application model.  When it debuted, it was revolutionary to have a fully typed, compiled OO framework that was virtually portable to mobile and desktop.  However, since then, ASP.Net has not done much to improve the initial offerings.  Yes, the 2.0 framework was much more robust, and VS 2005 had lots of IDE help for webmasters, but fundamentally, the same problems that held developers of 1.0 sites back are holding developers of 3.0 sites back - namely, the ASP.Net page lifecycle.</p>
<p>Viewstate and lifecycle events are still very confusing for new ASP.Net programmers.  There is no easy way for them to immediately "get it" - they have to spend the time in the trenches, watching their data disappear on post back, or double-bind, and flail around with building and rendering their own web controls.  They have to see the DataGrid spew its html diarrhea and spend hours customizing it.  They have to have that client ask them "what the hell is all this javascript, and why are the pages so big?" and figure out just what the heck all that gibberish on their pages are.</p>
<p>Moving up the experience chain, Viewstate and lifecycle events represent a significant amount of design and front-end time on a web application even for those that have been doing it for a while.  You have to balance your state management with your html optimization, caching, and application maintainability.  Often you have to build your own state-tracking structures or extend existing ones.  You have to carefully consider whether to roll your own custom controls or buy third party interfaces and rely on their javascript and state programming (or maybe their support team!)  And for very simple "read-only" web sites, viewstate just gets in the way.</p>
<p>So in summary, Viewstate and lifecycle are still be a pain in the butt, and still represent hurdles for new programmers.  Years ago, it was worth the annoyances and problems, because you could write strongly typed, object oriented portable code without getting lost in folders and folders of scripted sites.  So why might it be dying?  Well...</p>
<p>The first item on the agenda is <a href="http://silverlight.net/">Silverlight</a>.  ASP.Net represented significant advantages for writing portable code that was closer to classic desktop programming, as it abstracted out much of the xhtml.  But now I've seen web application developers swoon over Silverlight.  If their reaction is any indication, and the amount of momentum that Microsoft is putting into WPF, many shops are going to give up programming their internal or non-public projects in ASP.Net and move to Silverlight instead.   I'm personally still skeptical about Silverlight's market penetration, as there are many gaps it doesn't fill for content publishers.  But it's not a minor consideration.</p>
<p>Second is the new ASP.Net MVC framework.  MVC is an old model that's rapidly gaining traction in the web world, and with the introduction of the ASP.Net MVC framework, it is hard to see any clear advantage to the older webforms model.  From <a href="http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx">Scott Guthrie's Introductory MVC post</a> a couple months ago:</p>
<blockquote><p>To help enforce testability, the MVC framework today does not support postback events directly to server controls within your Views.  Instead, ASP.NET MVC applications generate hyperlink and AJAX callbacks to Controller actions - and then use Views (and any server controls within them) solely to render output.  This helps ensure that your View logic stays minimal and solely focused on rendering, and that you can easily unit test your Controller classes and verify all Application and Data Logic behavior independent of your Views. </p></blockquote>
<p>And finally, we come to REST, another model that is gaining traction.  True REST and webforms are mutually exclusive since REST involves heavy reliance on mapping resource locators to known states of an application.  This model has lots of advantages for web services and data-based applications, especially in the realms of testing, while ASP.Net Webform applications are often built around one URL for many states, using Viewstate and Session as your state map, which are of course lost between sessions and server restarts.  </p>
<p>So long story short... I think we're seeing the beginning of a new paradigm.  In 5 years, will anyone still be developing with true ASP.Net Webforms?  It will be interesting to see!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpvs.net/2008/04/25/aspnet-web-forms-dying-a-slow-death/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

