<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Joel Varty</title><subtitle type="html">A software architect's thoughts from &lt;a href="http://www.edentity.ca" style="text-decoration:underline"&gt;Edentity Web Systems&lt;/a&gt; in Toronto, Canada.  &lt;br/&gt;
Read my personal blog here: &lt;a href="http://joelvarty.com" style="text-decoration:underline"&gt;joelvarty.com&lt;/a&gt;</subtitle><id>http://weblogs.asp.net/joelvarty/atom.aspx</id><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/default.aspx" /><link rel="self" type="application/atom+xml" href="http://weblogs.asp.net/joelvarty/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2010-06-18T09:33:08Z</updated><entry><title>UX Fail: IE 9</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2011/07/29/ux-fail-ie-9.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2011/07/29/ux-fail-ie-9.aspx</id><published>2011-07-29T13:23:19Z</published><updated>2011-07-29T13:23:19Z</updated><content type="html">&lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/joelvarty/image_599AAE85.png" width="524" height="219" /&gt;&lt;/p&gt;  &lt;p&gt;The people who designed IE 9 did a poor job of copying Chrome’s nice and clean interface. &lt;/p&gt;  &lt;p&gt;Why oh WHY would the little button to change into compatibility mode (which shouldn’t be necessary at all) be the same size as the refresh button?&amp;#160; And why does the “stop” button never go away?&amp;#160; &lt;/p&gt;  &lt;p&gt;It’s all just wrong.&amp;#160; And IE 9 STILL causes layout issues all over the place.&amp;#160; Chrome, Firefox?&amp;#160; No problem, they update every few weeks with nary an problem that has even come close to the shitstorm that happens after an IE update.&amp;#160; &lt;/p&gt;  &lt;p&gt;Unacceptable.&amp;#160; &lt;/p&gt;  &lt;p&gt;I will only ever use it for testing.&lt;/p&gt;  &lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7889255" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author></entry><entry><title>Azure SDK 1.3: Error on Web Role Publish…</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2011/01/26/azure-sdk-1-3-error-on-web-role-publish.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2011/01/26/azure-sdk-1-3-error-on-web-role-publish.aspx</id><published>2011-01-26T15:21:33Z</published><updated>2011-01-26T15:21:33Z</updated><content type="html">&lt;p&gt;If you get this error:&lt;/p&gt;  &lt;p&gt;The &amp;quot;TransformXml&amp;quot; task failed unexpectedly.    &lt;br /&gt;System.UriFormatException: Invalid URI: The URI is empty.     &lt;br /&gt;&amp;#160;&amp;#160; at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)     &lt;br /&gt;&amp;#160;&amp;#160; at System.Uri..ctor(String uriString)     &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.Web.Publishing.Tasks.TransformXml.Execute()     &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()     &lt;br /&gt;&amp;#160;&amp;#160; at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean&amp;amp; taskResult)&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Check the web.config of any of your web roles for malformed XML – it could have been tweaked without your knowing it.&amp;#160; Here where my problem was:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;mailSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;smtp&lt;/span&gt; &lt;span class="attr"&gt;deliveryMethod&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Network&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;from&lt;/span&gt;=&amp;quot;&lt;span class="attr"&gt;My&lt;/span&gt; &lt;span class="attr"&gt;Site&lt;/span&gt; &amp;amp;&lt;span class="attr"&gt;amp&lt;/span&gt;;&lt;span class="attr"&gt;lt&lt;/span&gt;;&lt;span class="attr"&gt;support&lt;/span&gt;@&lt;span class="attr"&gt;mysite&lt;/span&gt;.&lt;span class="attr"&gt;com&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&amp;quot;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;network&lt;/span&gt; &lt;span class="attr"&gt;host&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;123.server.net&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;port&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;25&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;userName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;123&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;password&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;abc&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
         &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;smtp&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;mailSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;See it?&amp;#160; The email address in the from attribute has a &amp;gt; in.&amp;#160; Nasty.&amp;#160; Switch that thing back to &amp;amp;gt; and you should be good to go.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7690389" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="Azure" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Azure/default.aspx" /></entry><entry><title>Azure Deployment - Be careful adding a Remote Desktop connection to deployments that you want to swap staging with live…</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/12/07/azure-deployment-be-careful-adding-a-remote-desktop-connection-to-deployments-that-you-want-to-swap-staging-with-live.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/12/07/azure-deployment-be-careful-adding-a-remote-desktop-connection-to-deployments-that-you-want-to-swap-staging-with-live.aspx</id><published>2010-12-07T15:46:24Z</published><updated>2010-12-07T15:46:24Z</updated><content type="html">&lt;p&gt;Adding Remote Desktop capability adds an external endpoint onto the deployment, meaning it may have more endpoints that your current live deployment.&amp;#160; When there is a difference in the number of endpoints between a staging and live deployment, you can’t swap them in the Azure portal.&amp;#160; Oops.&lt;/p&gt;  &lt;p&gt;So you have to the remote capability to your live deployment first if you want to do this…&lt;/p&gt;  &lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7657720" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="Azure" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Azure/default.aspx" /></entry><entry><title>Error 400 with WCF REST Services</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/11/17/error-400-with-wcf-rest-services.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/11/17/error-400-with-wcf-rest-services.aspx</id><published>2010-11-17T14:15:45Z</published><updated>2010-11-17T14:15:45Z</updated><content type="html">&lt;p&gt;I recently worked on a site that had a strange issue where “sometimes” the WCF service (JSON encoding) that we accessed via JavaScript (using jQuery) was throwing an HTTP 400 error.&amp;#160; Setting a breakpoint at the web method itself was useless as it would never be hit.&lt;/p&gt;  &lt;p&gt;Well, it turns out it was a simple problem – WCF throws this error internally (via the JSONP Encoder) whenever a parameter cannot be parsed into the correct type.&amp;#160; In this case, an int parameter value was being read from a cookie that was returning null.&amp;#160; Changing the code to pass a -1 instead of null worked just fine.&amp;#160; In retrospect, it might even be smarter to pass the paramters as strings and parse them yourself.&amp;#160; At least that way you can control what formats are allowed and, moreover, you’ll understand what the devil is going on!&lt;/p&gt;  &lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7645889" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="AJAX" scheme="http://weblogs.asp.net/joelvarty/archive/tags/AJAX/default.aspx" /><category term="WCF" scheme="http://weblogs.asp.net/joelvarty/archive/tags/WCF/default.aspx" /><category term="jQuery" scheme="http://weblogs.asp.net/joelvarty/archive/tags/jQuery/default.aspx" /></entry><entry><title>Razor + Agilty will be a match made in heaven</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/10/20/razor-agilty-will-be-a-match-made-in-heaven.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/10/20/razor-agilty-will-be-a-match-made-in-heaven.aspx</id><published>2010-10-20T13:22:42Z</published><updated>2010-10-20T13:22:42Z</updated><content type="html">&lt;p&gt;I just finished reading Scott’s post on &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/10/19/asp-net-mvc-3-new-model-directive-support-in-razor.aspx" target="_blank"&gt;ASP.NET MVC 3 and the new @model key in&amp;#160; Razor&lt;/a&gt; and it got me thinking about how we could change Agility module output templates to support MVC with strongly typed partial views based on the module definition.&amp;#160; That way, you’d get intellisense in Visual Studio based on the types that are autogenerated from the Module Def and the definitions of any linked content.&amp;#160; &lt;/p&gt;  &lt;p&gt;Combine this on the backend with the ability to read any of the data on the front end in json or xml with OData and all of the sudden your Agility is unlocked and ready to rock.&lt;/p&gt;  &lt;p&gt;more (much more) later! &lt;/p&gt;  &lt;p&gt;joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7629063" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="Agility" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Agility/default.aspx" /><category term="MVC" scheme="http://weblogs.asp.net/joelvarty/archive/tags/MVC/default.aspx" /></entry><entry><title>Server Controls vs Plugins</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/09/23/server-controls-vs-plugins.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/09/23/server-controls-vs-plugins.aspx</id><published>2010-09-23T15:07:15Z</published><updated>2010-09-23T15:07:15Z</updated><content type="html">&lt;h4&gt;I think the ASP.NET world has changed completely as far as reusable code is concerned.&amp;#160; &lt;/h4&gt;  &lt;h4&gt;Let’s start with a bit of background…&lt;/h4&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Server Controls&lt;/h4&gt;  &lt;p&gt;I remember when making reusable code in ASP.NET meant writing custom server controls that had all kinds of logic for outputting complex html based on simple templating.&amp;#160; Heck, remember?&amp;#160; I still write and use these things all the time!&amp;#160; &lt;/p&gt;  &lt;p&gt;But wait a minute, what’re the server controls I hate the most?&amp;#160; Grid.&amp;#160; ListView.&amp;#160; Menu.&lt;/p&gt;  &lt;p&gt;What’re the ones I use the most?&amp;#160; Repeater.&amp;#160; Placeholder.&amp;#160; &lt;/p&gt;  &lt;p&gt;What the… ? The server controls I use the most DON’T EVEN OUTPUT HTML.&amp;#160; All they do is provide a way of controlling the output of HTML that &lt;em&gt;I put into the markup myself&lt;/em&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;That’s the key to a good server control: &lt;strong&gt;CONTROL.&amp;#160; &lt;/strong&gt;I mean, what good is a control that outputs a &amp;lt;table&amp;gt; tag when you want it to output an &amp;lt;ul&amp;gt; tag?&amp;#160; No good at all, I say.&lt;/p&gt;  &lt;h4&gt;&amp;#160;&lt;/h4&gt;  &lt;h4&gt;Plugins&lt;/h4&gt;  &lt;p&gt;I remember a time when I scoffed at Microsoft’s implementation of &lt;a href="http://msdn.microsoft.com/en-us/library/ms531079%28VS.85%29.aspx" target="_blank"&gt;DHTML behaviors in IE&lt;/a&gt; (I think they first appeared in 5.5).&amp;#160; I knew that the idea was profoundly useful in theory, but the DOM traversing and manipulation capabilities were so browser specific, not to mention the fact that they only worked in IE anyways) that it never had a chance.&amp;#160; &lt;/p&gt;  &lt;p&gt;But what was the idea behind “Behaviors?”&amp;#160; It was intended, in my opinion, to add interactive functionality to existing markup.&amp;#160; This includes the ability to inject additional DOM elements and unobtrusive Javascript events into a set of elements that were included in a given behavior.&amp;#160; &lt;/p&gt;  &lt;p&gt;“But Joel,” you say, “this is what a &lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt; plugin does!” &lt;/p&gt;  &lt;p&gt;Totally, I know.&amp;#160; Awesome idea, huh?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Reusable code in Repeaters and Plugins&lt;/h4&gt;  &lt;p&gt;Now, when I write a server control, it follows this pattern: &lt;strong&gt;Repeater + Plugin = Control&lt;/strong&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;Let’s take the example of site navigation.&amp;#160; Often, it’s useful to ouput this as a series of nested &amp;lt;ul&amp;gt; tags, which each page in the sitemap represented by a &amp;lt;li&amp;gt; tag.&amp;#160; This looks some what representative of the site structure when viewed with no css or interactivity – you see all of the pages in the site.&lt;/p&gt;  &lt;p&gt;Now, you could (and should) control a lot about how those lists look based on CSS rules.&amp;#160; You can give the first level certain formatting, and, for example, hide the sub-levels.&amp;#160; But how do you show the sub levels on mouse-over or click?&amp;#160; This is where the plugin logic comes in.&amp;#160; You can &lt;a href="http://docs.jquery.com/Plugins/Authoring" target="_blank"&gt;write a jQuery plugin&lt;/a&gt; to control the behavior of the &amp;lt;ul&amp;gt; and &amp;lt;li&amp;gt; elements based on user input, and it can all be done without including Javascript inside the markup (no document.write() or any crap like that).&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Where is this leading?&lt;/h4&gt;  &lt;p&gt;I am saying we shouldn’t be relying on crazy server controls to magically output html and Javascript to make pretty websites and apps.&amp;#160; &lt;/p&gt;  &lt;p&gt;May ASP.NET developers hate this idea – it means they have to actually think about the markup that will be produced by the stuff the put on their pages and user controls.&amp;#160; “Our world is crumbling!”&amp;#160; &lt;/p&gt;  &lt;p&gt;Well, I say suck it up – we should have paying more attention to client markup and less to server markup for the last 9 years or so.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;.Net without the ViewState&lt;/h4&gt;  &lt;p&gt;This is what I want to see!&amp;#160; This is why MVC is so cool, but most .Net developers will continue to ignore it, so what do we do?&amp;#160; Think about the pattern of &lt;strong&gt;Repeater + Plugin = Control&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I have one last suggestion to you, in the form of a challenge: in your next project, take out the &amp;lt;form runat=&amp;quot;server&amp;quot;&amp;gt; tag from the page or master page.&amp;#160; It will FORCE you to stop using control that rely on viewstate, and these are almost ALWAYS the ones that output crazy html and inline styles that suck when you want to have control over your markup.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7619487" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="AJAX" scheme="http://weblogs.asp.net/joelvarty/archive/tags/AJAX/default.aspx" /><category term="Javascript" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Javascript/default.aspx" /><category term="jQuery" scheme="http://weblogs.asp.net/joelvarty/archive/tags/jQuery/default.aspx" /></entry><entry><title>Amazon adds CloudFront API for content invalidation</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/09/01/amazon-cloudfront-add-api-for-content-invalidation.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/09/01/amazon-cloudfront-add-api-for-content-invalidation.aspx</id><published>2010-09-01T13:20:53Z</published><updated>2010-09-01T13:20:53Z</updated><content type="html">&lt;p&gt;&lt;img alt="Amazon Web Services" src="http://awsmedia.s3.amazonaws.com/logo_aws.gif" /&gt;&lt;/p&gt;  &lt;p&gt;Good news from Amazon this morning as they have announced what &lt;a href="http://weblogs.asp.net/joelvarty/archive/2010/04/13/amazon-cloudfront-cache-invalidation-fill-out-the-survey.aspx" target="_blank"&gt;I’ve been asking for&lt;/a&gt; – an API for content invalidation.&amp;#160; Previously, they allowed content to have a max-age of 1 hour, but it didn’t allow for the control that a manual invalidation would have.&amp;#160; According to the press release, the API call will allow for the removal of files from all edge locations.&amp;#160; A set of files can be removed as well.&lt;/p&gt;  &lt;p&gt;“Invalidation requests for the first 1,000 files each month are provided at no additional charge; above this level, there is a $0.005 charge for invalidating each additional file.”&lt;/p&gt;  &lt;p&gt;This is great news on 2 fronts:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It’s a great feature that was missing from an already solid product.&lt;/li&gt;    &lt;li&gt;It’s a sign that Amazon is listening to it’s customers and providing updates without deprecating existing APIs.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Here’s a screenshot of the API call from Amazon’s &lt;a href="http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/" target="_blank"&gt;CloudFront developer documentation&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/" target="_blank"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/joelvarty/image_539E3A87.png" width="530" height="279" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;via &lt;a href="http://aws.amazon.com/about-aws/whats-new/2010/08/31/cloudfront-adds-invalidation-feature/" target="_blank"&gt;Amazon Web Services&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;more later&amp;#160; - joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7602973" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="Cloud" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Cloud/default.aspx" /><category term="Amazon" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Amazon/default.aspx" /></entry><entry><title>VS 2010–Fix for hang on debugging ASP.Net 3.5 Apps…</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/08/26/vs-2010-fix-for-hang-on-debugging-asp-net-3-5-apps.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/08/26/vs-2010-fix-for-hang-on-debugging-asp-net-3-5-apps.aspx</id><published>2010-08-26T18:41:41Z</published><updated>2010-08-26T18:41:41Z</updated><content type="html">&lt;p&gt;Just got this in an email from Microsoft: &lt;/p&gt;  &lt;p&gt;Greetings from Microsoft Connect!   &lt;br /&gt;This notification was generated for feedback item: &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/556000/vs-2010-hangs-when-debugging-asp-net-3-5-web-application-or-website"&gt;VS 2010 - Hangs when debugging ASP.Net 3.5 web application or website&lt;/a&gt; which you submitted at the &lt;a href="http://connect.microsoft.com"&gt;Microsoft Connect&lt;/a&gt; site.    &lt;br /&gt;Hello,    &lt;br /&gt;The fix for this is now available for download and install from &lt;a href="https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=30738&amp;amp;wa=wsignin1.0"&gt;https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=30738&amp;amp;wa=wsignin1.0&lt;/a&gt;    &lt;br /&gt;or     &lt;br /&gt;&lt;a href="http://code.msdn.microsoft.com/KB2106584"&gt;http://code.msdn.microsoft.com/KB2106584&lt;/a&gt;    &lt;br /&gt;Best Regards,    &lt;br /&gt;Visual Studio Debugger&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Note: The fix for this issue was packaged with the fix for another issue, the KB article currently only lists the other issue, but this download does contain both fixes    &lt;br /&gt;You may receive a general &amp;quot;Feedback Item Updated&amp;quot; notification as well, if any other changes were made by Microsoft.    &lt;br /&gt;Thank you for using Microsoft Connect!    &lt;br /&gt;Regards,    &lt;br /&gt;the Microsoft Connect Team &lt;/p&gt;  &lt;p&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7600522" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="VS 2010" scheme="http://weblogs.asp.net/joelvarty/archive/tags/VS+2010/default.aspx" /></entry><entry><title>Getting comfortable with Javascript callbacks</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/08/26/getting-comfortable-with-javascript-callbacks.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/08/26/getting-comfortable-with-javascript-callbacks.aspx</id><published>2010-08-26T13:28:09Z</published><updated>2010-08-26T13:28:09Z</updated><content type="html">&lt;p&gt;It seems every language has it’s own way of implementing callbacks.&lt;/p&gt;  &lt;p&gt;Back in the VB days (daze?) we used the addressof operator and all kinds of win32 stuff to get app and activex control to do what we wanted.&lt;/p&gt;  &lt;p&gt;In C#, we have the delegate (and the anonymous delegate) that makes life pretty easy in terms of defining how to subscribe to a callback “even” and how to broadcast that callback.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Javascript callbacks are the simplest, and arguable the more nebulous, implementation of them all.&amp;#160; Once you understand how callbacks work, using libraries like &lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt;, and our own &lt;a href="http://developer.agilitycms.com/Documentation.aspx?section=37&amp;amp;doc=170" target="_blank"&gt;UGC Javascript API&lt;/a&gt; becomes much easier.&lt;/p&gt;  &lt;h3&gt;Why do we need it?&lt;/h3&gt;  &lt;p&gt;Think of the way code normal iterates from line to line.&amp;#160; It’s straightforward and simple: you loop over a list, and at the end of the loop, you keep going; you use an if statement, and after that you know that the condition has been met; similarily, when you call a method, you know that it has done all of its work and returned something useful.&amp;#160; Right?&amp;#160; Well… not always.&amp;#160; Sometimes that method will invoke web requests that need some time to process, or it may call another method that has to do some processing or is waiting for user input…&amp;#160; These kinds of operations can be implemented asynchronously, and the only way to manage that logic programmatically is with a callback parameter.&lt;/p&gt;  &lt;h3&gt;How does it work?&lt;/h3&gt;  &lt;p&gt;A callback parameter on a Javascript method is essentially passing a reference to the enter function definition into the method so that the method can call that function when it needs to.&lt;/p&gt;  &lt;p&gt;Here’s an example:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; doSomething(callback) {
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (somecondition()) {        
      callback(&lt;span class="kwrd"&gt;true&lt;/span&gt;);
    }
}

&lt;span class="kwrd"&gt;function&lt;/span&gt; entryPoint() {
    doSomething(&lt;span class="kwrd"&gt;function&lt;/span&gt;(yesOrNo) {
       &lt;span class="rem"&gt;//do something else&lt;/span&gt;
    });
}&lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;Let’s assume that the entryPoint() method is being called first.&amp;#160; It calls doSomething(), which in turn exits right away.&amp;#160; The only way that the entryPoint method will know what the doSomething method wanted to return is to pass in a function as a callback, and take the return value as parameter.&amp;#160; In this case, it’s a boolean value, but it could be anything (or more that one thing).&lt;/p&gt;

&lt;p&gt;A lot of the useful methods in the jQuery library use this logic, especially the &lt;a href="http://api.jquery.com/category/events/" target="_blank"&gt;unobtrusive event handlers&lt;/a&gt; on buttons or links.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;$(&lt;span class="str"&gt;&amp;quot;#btnSubmitForm&amp;quot;&lt;/span&gt;).click(function(e) {
    e.preventDefault();
    &lt;span class="rem"&gt;//do something&lt;/span&gt;
});&lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;Notice how the click method takes a function parameter, which in turn has a “e” parameter with the event data from the button click.&lt;/p&gt;

&lt;p&gt;Now let’s look at how &lt;a href="http://api.jquery.com/category/ajax/" target="_blank"&gt;Urls can be invoked asynchronously&lt;/a&gt; (remember the first letter of the AJAX acronym is asynchronous).&lt;/p&gt;

&lt;pre class="csharpcode"&gt;$.ajax({
  url: &lt;span class="str"&gt;'path/handler.ext'&lt;/span&gt;,
  success: function(data) {
     &lt;span class="rem"&gt;//do something with the data&lt;/span&gt;
  },
  error : function(request, errorType, exception) {
     &lt;span class="rem"&gt;//handle the error&lt;/span&gt;
  }
});&lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;You’ll notice that this implementation is a bit different – the ajax method from jQuery is passed an object that has several fields defining how that method is meant to behave.&amp;#160; The first one here is the Url, which will be invoked.&amp;#160; Then we have 2 separate functions that are passed in – one for the success condition that is passed the data that was returned from the Url handler, and another with the error condition.&amp;#160; &lt;/p&gt;

&lt;p&gt;There is also a way to invoke the ajax method synchronously, such that it blocks the calling method until the web request handling is complete, but that may cause the user’s browser to appear frozen if the request takes a long time, so be super careful with this one.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;var html = $.ajax({
  url: &lt;span class="str"&gt;&amp;quot;filepath.ext&amp;quot;&lt;/span&gt;,
  async: &lt;span class="kwrd"&gt;false&lt;/span&gt;
 }).responseText;&lt;/pre&gt;

&lt;p&gt;&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;

&lt;p&gt;There are lots of other things to consider when using callbacks in Javascript.&amp;#160; Mostly, you’ll need to be able to quickly refer to whatever documentation is available so that you can determine with the expected parameters and fields are for each callback function itself.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7600394" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="AJAX" scheme="http://weblogs.asp.net/joelvarty/archive/tags/AJAX/default.aspx" /><category term="Javascript" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Javascript/default.aspx" /><category term="jQuery" scheme="http://weblogs.asp.net/joelvarty/archive/tags/jQuery/default.aspx" /></entry><entry><title>Twitter OAuth Authentication with TweetSharp</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/08/12/twitter-oauth-authentication-with-tweetsharp.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/08/12/twitter-oauth-authentication-with-tweetsharp.aspx</id><published>2010-08-12T14:11:14Z</published><updated>2010-08-12T14:11:14Z</updated><content type="html">&lt;p&gt;&lt;a href="http://dev.twitter.com/" target="_blank"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 9px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image[10]" border="0" alt="image[10]" align="right" src="http://weblogs.asp.net/blogs/joelvarty/image10_1FAE2EF6.png" width="274" height="213" /&gt;&lt;/a&gt;The Twitter API is something that you may have learned to love and hate over the last while, but as of August 16th, you may have to change the way you access it.&amp;#160; &lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Basic Authentication is Going Away&lt;/h3&gt;  &lt;p&gt;Previously, the easiest way to authenticate a Twitter app was to ask for a user’s credentials and pass them directly to the Twitter API in the Authentication HTTP Header.&amp;#160; This is, incidentally, how any site that uses basic authentication behaves.&amp;#160; Your credentials are passed in a base64 encoded string in the header on EVERY request.&amp;#160; Encoded – not encrypted.&amp;#160; So if the site isn’t using SSL (and Twitter doesn’t) you could be exposing credentials to anyone who wants to sniff them.&lt;/p&gt;  &lt;p&gt;Twitter has acknowledged this fact, and has provided an OAuth alternative based on an open and accepted standard of token based authentication.&amp;#160; Up until now, though, the OAuth standard has not been enforced, since it was more of a development hurdle for folks who just wanted to get their work out there and were willing to accept the risk of sniffed credentials.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;The OAuth Authorization and Authentication Process&lt;/h3&gt;  &lt;p&gt;What do we mean by authorization versus authentication?&amp;#160; Authorization is the process by which an end user of your Twitter app (if you haven’t created one of these yet, do it &lt;a href="http://dev.twitter.com/apps/new" target="_blank"&gt;here&lt;/a&gt;) will allow it to access their account.&amp;#160; This is done in a browser window, and the user, once they’ve clicked “Allow Access” will be presented with a short PIN sequence will they will have to copy and paste or enter manually into your application.&amp;#160; Given that PIN, your app will have the ability to create (and store) an OAuth Token and Secret that will allow your app access to that Twitter account until access is denied.&lt;/p&gt;  &lt;p&gt;Every request you send to Twitter (either for new status updates or for queries) should have that token provided as a credential.&amp;#160; This will mark any status updates with your application’s name and provide a link for other users to go to your application URL.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Here the Step by Step Process for Authorization&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://dev.twitter.com/apps/new" target="_blank"&gt;Create a Twitter App&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;keep track of your Consumer Key and Secret, you’ll need these &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Generate an unauthorized token &lt;/li&gt;    &lt;li&gt;Generate a authorization and direct your user’s browser to it &lt;/li&gt;    &lt;li&gt;Give your user the opportunity to enter the PIN into your app &lt;/li&gt;    &lt;li&gt;Generate the authorized token and secret &lt;/li&gt;    &lt;li&gt;Persist the token and secret &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;TweetSharp and other OAuth Libraries&lt;/h3&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image[6]" border="0" alt="image[6]" src="http://weblogs.asp.net/blogs/joelvarty/image6_48891E32.png" width="275" height="83" /&gt;&lt;/p&gt;  &lt;p&gt;In its own OAuth FAQ, Twitter mentions that you really shouldn’t tackly OAuth with raw HTTP requests (although you can if you want).&amp;#160; The fact of the matter is that there are lots of different wrappers written for OAuth itself, which could in theory be used with any standard OAuth provided (Google and Yahoo also use OAuth) as well provider specific wrappers written to give you a high level access to the logical functions of the system you are accessing.&lt;/p&gt;  &lt;p&gt;TweetSharp is a very nice .Net API for Twitter, but it’s authors have based it upon another library that they built, the more generic &lt;a href="http://hammock.codeplex.com/" target="_blank"&gt;Hammock&lt;/a&gt; which they are still actively developing.&amp;#160; Apparently &lt;a href="http://tweetsharp.codeplex.com/Thread/View.aspx?ThreadId=213604" target="_blank"&gt;nobody has been helping them build TweetSharp&lt;/a&gt;, so they are leaving it for the community to work on from now on.&lt;/p&gt;  &lt;p&gt;One of the things that TweetSharp makes super simple is the generation of the Tokens and Authorization URL that I outlined above.&amp;#160; &lt;/p&gt;  &lt;p&gt;First of all, &lt;a href="http://tweetsharp.codeplex.com/releases/view/45794" target="_blank"&gt;download the TweetSharp API&lt;/a&gt; and add a reference in your app to the TweetSharp and TweetSharp.Twitter assemblies.&lt;/p&gt;  &lt;p&gt;The follow code snippets are all that you need after that:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; TweetSharp.Model;
&lt;span class="kwrd"&gt;using&lt;/span&gt; TweetSharp.Twitter.Extensions;
&lt;span class="kwrd"&gt;using&lt;/span&gt; TweetSharp.Twitter.Fluent;
&lt;span class="kwrd"&gt;using&lt;/span&gt; TweetSharp.Twitter.Model;
&lt;span class="kwrd"&gt;using&lt;/span&gt; TweetSharp.Twitter.Service;

&lt;span class="rem"&gt;//generate the token and url that will we need&lt;/span&gt;
OAuthToken unauthorizedToken = service.GetRequestToken(twitterConsumerKey, twitterConsumerSecret);
&lt;span class="kwrd"&gt;string&lt;/span&gt; url = service.GetAuthorizationUrl(unauthorizedToken);

&lt;span class="rem"&gt;//TODO: get the pin from the user&lt;/span&gt;

&lt;span class="rem"&gt;//once you have the pin from the user, build your authorized token&lt;/span&gt;
OAuthToken authToken = service.GetAccessToken(twitterConsumerKey, twitterConsumerSecret, unauthToken, pin);

&lt;span class="rem"&gt;//store the authToken.Token, and the authToken.TokenSecret&lt;/span&gt;

&lt;span class="rem"&gt;//make an authenticated call&lt;/span&gt;
var service = &lt;span class="kwrd"&gt;new&lt;/span&gt; TwitterService();
service.AuthenticateWith(twitterConsumerKey, twitterConsumerSecret, syndicationService.OAuthToken, syndicationService.OAuthTokenSecret);
&lt;span class="kwrd"&gt;if&lt;/span&gt; (service.Error == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
{
    TwitterStatus status = service.SendTweet(&lt;span class="kwrd"&gt;value&lt;/span&gt;);
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;TweetSharp also has some nice documentation on this process, and a couple of different methods that you can do it &lt;a href="http://tweetsharp.codeplex.com/wikipage?title=OAuthWorkflow&amp;amp;referringTitle=OAuthWalkthrough" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;more later – joel&lt;/p&gt;

&lt;p&gt;&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7589831" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="OAuth" scheme="http://weblogs.asp.net/joelvarty/archive/tags/OAuth/default.aspx" /><category term="Twitter" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Twitter/default.aspx" /></entry><entry><title>JavaScript Compilation: Is this what will turn the web into the new desktop?</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/07/23/javascript-compilation-is-this-what-will-turn-the-web-into-the-new-desktop.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/07/23/javascript-compilation-is-this-what-will-turn-the-web-into-the-new-desktop.aspx</id><published>2010-07-23T13:21:06Z</published><updated>2010-07-23T13:21:06Z</updated><content type="html">&lt;h3&gt;The Web is the New Desktop&lt;/h3&gt;  &lt;p&gt;Can we finally expect to see web browser truly competing with native apps?&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/b/ie/archive/2009/11/18/an-early-look-at-ie9-for-developers.aspx" target="_blank"&gt;IE 9&lt;/a&gt; does JavaScript in the background on the first load of a page, running in non-compiled mode until the scripts are ready, and then they run from the native commands after that.&amp;#160; It is detailed &lt;a href="http://blogs.msdn.com/b/ie/archive/2010/03/18/the-new-javascript-engine-in-internet-explorer-9.aspx" target="_blank"&gt;here&lt;/a&gt; on the IE MSDN blog.&amp;#160; They talk about going beyond the benchmarks, which look like this:&lt;/p&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://ieblog.members.winisp.net/images/Dean_MIX10_2.png" /&gt;&lt;/p&gt;  &lt;p&gt;Going beyond the benchmarks means thinking about how the web page as a whole responds to the user in a practical way, and JavaScript performance is just one part of that.&amp;#160; Frankly, this is kind of ironic coming from the teams that put out IE7 and 8, because they talked about the same things when those things were introduced.&amp;#160; I think the problems with the legacy IE codebase is exactly that – too much legacy bloat.&lt;/p&gt;  &lt;p&gt;Most of the gains you see with IE 9 are about the JavaScript compilation happening on a second core, and hardware acceleration.&amp;#160; Ars Technica covered that &lt;a href="http://arstechnica.com/microsoft/news/2009/11/javascript-graphics-performance-improvements-on-tap-for-ie9.ars" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;But IE isn’t the only browser going that way – &lt;a href="http://www.conceivablytech.com/882/products/first-look-google-releases-chrome-6-preview/" target="_blank"&gt;Google is putting 2D acceleration into Chrome 6&lt;/a&gt; and the Mozilla team are getting it into &lt;a href="http://blog.mozilla.com/joe/2010/05/25/hardware-accelerating-firefox/" target="_blank"&gt;Firefox for HTML5 elements&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Mobile Web is the New Desktop&lt;/h3&gt;  &lt;p&gt;On the phone OS side of things, Android 2.2 introduces a similar behaviour to what IE 9 is doing with JIT&amp;#160; (Just In Time) compilation. &lt;/p&gt;  &lt;div style="padding-bottom: 0px; padding-left: 0px; width: 580px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:7d9f4e48-c85c-44ba-ae39-e735a398ba45" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=Ls0tM-c4Vfo&amp;amp;hl=en_US&amp;amp;fs=1?border=1" target="_new"&gt;&lt;img src="http://weblogs.asp.net/blogs/joelvarty/video365c58a4102a_4E0FF3EC.jpg" style="border-style: none" galleryimg="no" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;Currently, I am using an iPhone or iPad for mobile browsing, so while I can’t &lt;a href="http://arstechnica.com/gadgets/news/2010/07/android-22-demolishes-ios4-in-javascript-benchmarks.ars" target="_blank"&gt;compare performance to Android&lt;/a&gt;, I certainly welcome the competition.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://static.arstechnica.com/assets/2010/07/ios_v_android-thumb-640xauto-15275.png" width="491" height="368" /&gt;&lt;/p&gt;  &lt;p&gt;Also, it’s useful to note that the &lt;a href="http://blogs.blackberry.com/2010/07/blackberry-6-another-sneak-peek/" target="_blank"&gt;Blackberry 6.0 OS will be using a webkit based browser&lt;/a&gt;, so that’s reassuring.&amp;#160; Coding for Blackberry browsers is a real challenge at the moment.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; padding-left: 0px; width: 580px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:a41dd44c-017f-4158-a0fe-3ecfc5c36856" class="wlWriterEditableSmartContent"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=plWOkI_Urwo&amp;amp;hl=en_US&amp;amp;fs=1?border=1" target="_new"&gt;&lt;img src="http://weblogs.asp.net/blogs/joelvarty/videoaeaa9d5877d1_0AE475BF.jpg" style="border-style: none" galleryimg="no" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;What does this all mean?&amp;#160; It’s a great time to be a web developer, but don’t sit on your laurels!&amp;#160; CLient side programming in the browser is getting a whole lot more interesting.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7572406" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="Javascript" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Javascript/default.aspx" /><category term="iPad" scheme="http://weblogs.asp.net/joelvarty/archive/tags/iPad/default.aspx" /><category term="iPhone" scheme="http://weblogs.asp.net/joelvarty/archive/tags/iPhone/default.aspx" /><category term="IE9" scheme="http://weblogs.asp.net/joelvarty/archive/tags/IE9/default.aspx" /><category term="Chrome" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Chrome/default.aspx" /></entry><entry><title>jQuery Code Snippets for Visual Studio 2010</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/07/21/jquery-code-snippets-for-visual-studio-2010.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/07/21/jquery-code-snippets-for-visual-studio-2010.aspx</id><published>2010-07-21T18:30:15Z</published><updated>2010-07-21T18:30:15Z</updated><content type="html">&lt;p&gt;These are just genius.&amp;#160; I especially like the one for adding an AJAX call to an asmx, which is always a pain.&lt;/p&gt;  &lt;p&gt;&lt;a title="http://jquerysnippets.codeplex.com/documentation?referringTitle=Home" href="http://jquerysnippets.codeplex.com/documentation?referringTitle=Home"&gt;http://jquerysnippets.codeplex.com/documentation?referringTitle=Home&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;There is a quick demo of them &lt;a href="http://screencast.com/t/YjUyNDVjZD" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Type in &lt;strong&gt;jqajax&lt;/strong&gt;, and follow the intellisense…&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/joelvarty/image_0699230B.png" width="321" height="271" /&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Gives you this…&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/joelvarty/image_583F9D5D.png" width="357" height="152" /&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Nice time saver.&amp;#160; The plugin template is good too.&lt;/p&gt;  &lt;p&gt;more later – joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7570748" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="VS 2010" scheme="http://weblogs.asp.net/joelvarty/archive/tags/VS+2010/default.aspx" /><category term="jQuery" scheme="http://weblogs.asp.net/joelvarty/archive/tags/jQuery/default.aspx" /></entry><entry><title>Programming for APIs</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/07/20/programming-for-apis.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/07/20/programming-for-apis.aspx</id><published>2010-07-20T13:42:29Z</published><updated>2010-07-20T13:42:29Z</updated><content type="html">&lt;p&gt;There seems to be as much or more attention paid to “Apps” these days as there is to websites.&amp;#160; Whether it be for iOS, Android, Blackberry, Adobe AIR, Silverlight or even the (gasp) Desktop, we as “web” programmers are often called upon to implement APIs for these things.&amp;#160; &lt;/p&gt;  &lt;p&gt;Sometimes it’s in addition to a website, and sometimes it’s a stand alone API that is only meant to service a specific need for a specific app. In either case, it’s a good bet that can easily get cornered by the temptation to do what you’ve done before.&amp;#160; Usually, for Asp.Net folks, it means a simple asmx or (better still) a WCF service that can be controlled through configuration.&amp;#160; Either of these choices is fine, but if you are just envisioning the scope of what you are doing, you need to step back from the actual implementation details and ensure that the functionality you wish provide from this API is not reliant on the service technology itself.&lt;/p&gt;  &lt;p&gt;Just start from a basic data API, but keep in mind that everything you are working with may need to be stateless.&amp;#160; That means no session state,&amp;#160; no reliance on cached values (since your code could be deployed to a web farm) and no (or few) global variables.&amp;#160; Once you’ve cut all the crap and spaghetti code from what will become your data access layer, you can be left with a set of simple methods that take some parameters and return an object or collection of objects.&amp;#160; &lt;/p&gt;  &lt;p&gt;Sounds easy to test, doesn’t it? That’s the point!&amp;#160; You should be able to test the whole API before you even decide on whether the service is SOAP, JSON, ATOM or whatever.&amp;#160; I recommend you do that.&amp;#160; One thing to note, is that I would be wary, at this point, of copying and pasting code from “getting started” tutorials.&amp;#160; By all means, read those tutorials and understand what they are doing, but don’t feel that you have to jump into one technology or some pattern that doesn’t resonate with you after playing around with it.&amp;#160; Sometimes a standard data layer with static methods and custom objects calling custom written stored procedures in a database or writing files or whatever, is better than relying on some generic layer of logic like LINQ-SQL, Entity framework or nHibernate.&amp;#160; Not that I’m saying you shouldn’t use these technologies, they can make your life MUCH easier and speed your implementation process up greatly.&amp;#160; But it can also introduce unnecessary complexity into what should be a simple process of moving data from one tier or layer into another.&amp;#160; Always remember that simple is better, and anything you don’t understand isn’t simple because you won’t be figure out what’s wrong if it breaks.&lt;/p&gt;  &lt;p&gt;When you come to your objects that will store the data, be wary of using object that are creating by another framework like LINQ-SQL or Entity framework.&amp;#160; These objects are sweet as a starting point because you don’t have to worry about all that typing, but you may run into situations where the serialization required by your specific object on a specific service protocol will need customization that you can’t do in a partial class.&amp;#160; I won’t go into specifics here, but if you don run into the situation where you need to create your own custom objects, don’t hesitate.&amp;#160; Just do what you need to do to ensure you understand how your objects are being created, serialized and de-serialized.&amp;#160; It will be simpler and more reliable in the long run.&lt;/p&gt;  &lt;p&gt;Now you’ve got a data access and/or a business logic layer that you can test, and you should go ahead and do that before you start implementing the service itself.&amp;#160; You probably won’t, but knowing that you should have will help out later.&lt;/p&gt;  &lt;p&gt;At this point, if you can, use Asp.Net 4.0.&amp;#160; If you can’t ask yourself why not.&amp;#160; Ask everyone why not.&amp;#160; Do some research on WCF in .Net 4.0 (the biggest kicker is that in .Net 4.0 you don’t need to worry about multiple host headers screwing with your service).&amp;#160; If folks won’t listen to you, start arguing and argue with all your might that you need to code this API in Asp.Net 4.0.&amp;#160; Trust me, it will be worth the time you spend convincing yourself and them.&lt;/p&gt;  &lt;p&gt;Now, make a decision and either code the thing for OData or simply implement it in WCF.&amp;#160; Those are the only real choices that make sense, as far as I am concerned.&amp;#160; WCF lets you do REST style APIs or SOAP style without re-coding everything, but OData is better.&amp;#160; Why OData?&amp;#160; Do some research on that too, and you’ll find out that in the real world, your API will be most useful in one of two formats: XML and JSON.&amp;#160; OData does XML in Atom format, so it’s inherently readable in most browsers.&amp;#160; OData lets you flip to JSON or JSONp without messing with your API.&amp;#160; WCF is OK, but OData, if you can get your head around it, tends to be much better.&lt;/p&gt;  &lt;p&gt;Oh, and &lt;a href="http://www.odata.org/" target="_blank"&gt;OData&lt;/a&gt; in .Net 4 is implemented as &lt;a href="http://msdn.microsoft.com/en-us/library/cc668792%28VS.100%29.aspx" target="_blank"&gt;WCF Data Services&lt;/a&gt;.&amp;#160; It used to be called ADO.Net data services.&amp;#160; &lt;/p&gt;  &lt;p&gt;There are also a ton of &lt;a href="http://www.odata.org/developers/odata-sdk" target="_blank"&gt;client SDKs&lt;/a&gt; for OData, but XML is so easy to consume, your API consumers will be able to see the value of your API with just&amp;#160; a browser.&amp;#160; &lt;/p&gt;  &lt;p&gt;That’s the real point – with a well written, simple and testable data layer, and OData on top of that, your API services will be reliable and elegant to use.&amp;#160; Folks will WANT to use APIs that are easy to understand and reliable.&lt;/p&gt;  &lt;p&gt;more later – joel.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7570080" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="WCF" scheme="http://weblogs.asp.net/joelvarty/archive/tags/WCF/default.aspx" /><category term=".Net 4.0" scheme="http://weblogs.asp.net/joelvarty/archive/tags/.Net+4.0/default.aspx" /><category term="ODATA" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ODATA/default.aspx" /></entry><entry><title>Thoughts on Azure – Compute, Storage and SQL</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/06/22/thoughts-on-azure-compute-storage-and-sql.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/06/22/thoughts-on-azure-compute-storage-and-sql.aspx</id><published>2010-06-22T13:50:10Z</published><updated>2010-06-22T13:50:10Z</updated><content type="html">&lt;p&gt;I think Azure is ready to go as a platform for a Software as a Service platform.&amp;#160; When we think of cloud-based infrastructures, it has many pieces that make it both viable and attractive from many points of view.&amp;#160; For one, it’s hooked tightly into a great development tool in Visual Studio 2010, and the &lt;a title="Windows Azure Software Development Kit (June 2010)" href="http://www.microsoft.com/downloads/details.aspx?familyid=21910585-8693-4185-826E-E658535940AA&amp;amp;displaylang=en" target="_blank"&gt;latest SDK&lt;/a&gt; and &lt;a title="Windows Azure Tools for Microsoft Visual Studio 1.2 (June 2010)" href="http://www.microsoft.com/downloads/details.aspx?familyid=2274A0A8-5D37-4EAC-B50A-E197DC340F6F&amp;amp;displaylang=en" target="_blank"&gt;Tools&lt;/a&gt; make it a simply process to publish to the cloud directly from the IDE.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/joelvarty/image_48086C18.png" width="459" height="387" /&gt; &lt;/p&gt;  &lt;p&gt;On top of this, you can also hook into your Compute and Storage account right from Visual Studio Server Explorer windows, which is nice.&lt;/p&gt;  &lt;h3&gt;So what is Azure, really?&lt;/h3&gt;  &lt;p&gt;I attended a technical briefing for Microsoft partners in Toronto last week, and this was the biggest question.&amp;#160; I think there is a lot of misconception out there about what is offered and was is possible with Azure.&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Windows Azure - Compute&lt;/h4&gt;  &lt;p&gt;To&amp;#160; be quite blunt, this is primarily meant for Web Apps and Web Services, with the Compute platform tailored to what are called “Web Roles” and “Worker Roles”.&amp;#160; These can ONLY to be coded in managed code, however they can invoke executables written in whatever language you like.&amp;#160; Basically, a web role is a web app, and do pretty much anything a web app can do.&amp;#160; A worker role is akin to a windows service, and if you’ve coded your windows services with decent separation of concerns, you should be port one of those over with no difficulty.&lt;/p&gt;  &lt;p&gt;The real power of the Compute platform is that is allows you to manually ramp up the number and size of Instances (read: Virtual Machines) that you want the app to be deployed, both for Web and Worker roles.&amp;#160; This means you can flip a config variable and ramp up the power without ever calling IT or touching any routers or load balancers or anything.&amp;#160; If you have a multi-tenanted app, this is nice.&amp;#160; If not, if you have a an app that’s is single-server, uses a ton of session, is coded like the tutorials, and isn’t meant to be publically available… you might want to reconsider if you need a cloud solution at all.&lt;/p&gt;  &lt;p&gt;What’s really good here is that, as of June 2010,&amp;#160; .Net 4.0 is supported in Compute.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Windows Azure – Storage&lt;/h4&gt;  &lt;p&gt;Table Storage – this is really “entity” storage (I know, I know, kind of the same thing), but really this is just a serialized object repository which the ability to be queried in OData style using the Data Services API.&amp;#160; Basically, you can dump objects in and get them out again.&amp;#160; It has automatic partitioning based on a partition key, meaning this is very scalable.&amp;#160; What stinks about it right now is that it only supports a pretty small subset of the OData (and therefore Data Serviecs) specification. &lt;/p&gt;  &lt;p&gt;Blob Storage&lt;/p&gt;  &lt;p&gt;Blobs equal files.&amp;#160; You can do block (sequential, or streamed) blobs or “paged blobs”.&amp;#160; These are not good names, but who cares?&amp;#160; The biggest annoyance is that it isn’t as good as Amazon S3 (yet), except that it’s stored in the same environment as your Compute instance(s), meaning that you don’t pay for data transfer to and from the Compute and Storage.&amp;#160; You only pay for data transfer in and out of Azure itself.&amp;#160; &lt;/p&gt;  &lt;p&gt;Queue Storage&lt;/p&gt;  &lt;p&gt;A queue where items live for up to seven days, 8kb string max.&amp;#160; Useful for implementing a multi-instance worker role pattern where the web roles create items in the queue and they are processed by an offline worker role.&amp;#160; These are not MSMQ, but they are still wicked useful.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;SQL Azure&lt;/h4&gt;  &lt;p&gt;Databases in the cloud.&amp;#160; Great!&amp;#160; Except that you can’t do Table partitioning based on filegroup, which is major pain.&amp;#160; The only way to scale is to do what is called &lt;a href="http://geekswithblogs.net/hroggero/archive/2010/05/28/sql-azure-notes-on-building-a-shard-technology.aspx" target="_blank"&gt;database sharding&lt;/a&gt;.&amp;#160; I’m hoping I can hold out until we can do something less useless.&amp;#160; I don’t want to rewrite app code and join data in my data access layer.&amp;#160; That defeats the purpose of SQL Server at all.&lt;/p&gt;  &lt;p&gt;To be continued…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Windows Azure AppFabric&lt;/h4&gt;  &lt;p&gt;The most important thing about Azure AppFabric is to know that it is NOTHING like &lt;a href="http://msdn.microsoft.com/en-us/windowsserver/ee695849.aspx" target="_blank"&gt;Windows Server AppFabric&lt;/a&gt;.&amp;#160; Which is too bad – because there isn’t yet a decent solution for distributed caching Azure Compute… a real shame.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;All in all, Azure is the real deal, and you’d do well to research this carefully – the naming of the technology has changed over the last 18 months and there is as much misinformation and rumor out there as anything else.&amp;#160; If in doubt, stick with what &lt;a href="http://www.microsoft.com/windowsazure/" target="_blank"&gt;MSDN&lt;/a&gt; tells us.&lt;/p&gt;  &lt;p&gt;more later - joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7539480" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term=".Net 4.0" scheme="http://weblogs.asp.net/joelvarty/archive/tags/.Net+4.0/default.aspx" /><category term="Azure" scheme="http://weblogs.asp.net/joelvarty/archive/tags/Azure/default.aspx" /></entry><entry><title>Adding OpenID to your own domain</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/joelvarty/archive/2010/06/18/adding-openid-to-your-own-domain.aspx" /><id>http://weblogs.asp.net/joelvarty/archive/2010/06/18/adding-openid-to-your-own-domain.aspx</id><published>2010-06-18T13:33:08Z</published><updated>2010-06-18T13:33:08Z</updated><content type="html">&lt;p&gt;This is something I’ve been pondering for a while – and this article makes it seem pretty simple.&lt;/p&gt;  &lt;p&gt;via &lt;a href="http://lifehacker.com/5566470/how-to-set-up-openid-on-your-own-domain" target="_blank"&gt;Lifehacker&lt;/a&gt; via &lt;a href="http://smarterware.org/6286/how-to-set-up-openid-on-your-own-domain" target="_blank"&gt;Smarterware&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;more later - Joel&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7535386" width="1" height="1"&gt;</content><author><name>joelvarty</name><uri>http://weblogs.asp.net/members/joelvarty.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/joelvarty/archive/tags/ASP.NET/default.aspx" /><category term="OpenID" scheme="http://weblogs.asp.net/joelvarty/archive/tags/OpenID/default.aspx" /></entry></feed>
