<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>The .NET Addict's Blog</title><link>http://dotnetaddict.dotnetdevelopersjournal.com/</link><description>The obsessive ramblings of a man hopelessly addicted to all things programming, including .NET, C#, Networking, Gaming, and much more.</description><copyright>Copyright 2009 dotnetaddict.dotnetdevelopersjournal.com</copyright><generator /><lastBuildDate>Thu, 05 Nov 2009 14:50:00 GMT</lastBuildDate><image><title>The .NET Addict's Blog</title><url>http://files.blog-city.com//files/J05/88284/p/f/penfold.jpg</url><link>http://dotnetaddict.dotnetdevelopersjournal.com/</link></image><ttl>360</ttl><docs>http://backend.userland.com/rss</docs><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/dotnetaddict" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Installing Geneva Beta 2 on Windows7</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/genevab2_win7.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/genevab2_win7.htm</link><pubDate>Thu, 05 Nov 2009 13:38:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=genevab2%5Fwin7</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Recently I installed the Beta 2 version of &quot;Geneva&quot;, or ADFS 2.0. All of my machines are now Windows 7&nbsp;machines, including just about all of my VHDs and virtual machines. The only time I use Win2k8 R2 is when the product I&#39;m installing specifically requires me to do that. So when I installed Geneva on my Win7 box, I thought everything would be fine.</p><p>Then I rebooted. The &quot;Modify STS Reference...&quot; and &quot;Update federation metadata&quot; menu items that are supposed to be added to the list of available options on an ASP.NET web application were gone. They were there before I rebooted but they were gone after. I also noticed something funny with the Identity training kit install. Every single directory and file in there was marked as &quot;read only&quot;. I would unset the read-only flag, right click the file, get properties, and sure enough, <em>it was still set to read only</em>. WTF?</p><p>Turns out that when I download files from the big bad scary internet, Windows 7 automatically flags them as &quot;bad content&quot; and they are blocked. The permissions of those files are significantly less than those of files I put onto my computer via DVD or whatever. This is actually as it should be, and it&#39;s designed to keep me from doing horribly bad things to my computer. </p><p>I uninstalled the Geneva SDK and the Identity Training Kit. I then right-clicked each of the <em>.msi</em> files, chose Properties and then clicked the magic <em><strong>Unblock</strong></em> button. After this, when I installed the Framework SDK, the Visual Studio extensions remained after reboot, and the files created by the identity training kit didn&#39;t have weird permission problems and the certificates installed by the lab set up actually bound to the SSL port properly.</p><p>So, the moral of the story is this: If you&#39;re going to install an MSI that you downloaded from a trusted source (like MSDN or Microsoft Downloads or h0tpr0n.com), unblock it before you install just to make sure you don&#39;t run into any goofy permission issues.</p>]]></description><category>geneva</category><category>identity</category><category>vs2008</category><category>windows7</category></item><item><title>Why we're all NOT going to die on December 21st, 2012.</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/maya_2012.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/maya_2012.htm</link><pubDate>Wed, 04 Nov 2009 21:02:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=maya%5F2012</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Unless you&#39;ve been living under a rock for the past couple of months, you&#39;ve probably not been able to escape the movie trailers, hype, and even SyFy channel (yes, SYFY channel..that should TELL YOU SOMETHING) specials regarding the Mayan &quot;prediction&quot; that the world will end in 2012.</p><p>First, some background on the Mayan calendar. The &quot;long count&quot; Mayan calendar is based, basically (I am oversimplifying a little bit), on interlocking wheels. You can think of these as gears where as the days pass, a bigger gear of seasons pass, which then slowly causes another bigger gear to pass. Finally, you end up with a gear that marks the passing of ages that marks the passage of a total of 26,000 years. There are 13 of these ages on the &quot;big gear&quot;. </p><p>The Mayan long count calendar reaches 13.0.0.0.0 on December 21st, 2012. Does this mean that the world is going to come to an end on that date? Does this mean that a huge apocalypse is going to rip the earth apart in huge explosions and other hollywood-like demolitions? Are we all going to cease to exist as time itself comes to a crashing halt?</p><p>UM. <strong><em><u>NO</u></em></strong>.</p><p>What we&#39;re looking at here is the Mayan equivalent of the Y2K problem. The Mayans, when constructing their calendars and the wheels/gears/ whatever they call them - constructed them to mark the passing of 26,000 years. When you think about how long that is, its a ridiculous amount of time. They probably said to themselves, &quot;Nobody is ever going to need more than 26,000 years on a calendar.&quot; Well, let&#39;s see. Where have we heard that mistake before? Oh yeah: <em>No one is ever going to need 4 digits to store a year in a piece of computer software</em>.</p><p>So if you&#39;re smart, you&#39;ll get people to give you all their worldy possessions on December 20th, 2012. Then, on December 22nd, 2012 - sell them all back at a premium. Call it the &quot;sucker surcharge&quot;, a fee for being such a gullable moron that they believed the world was going to end because a civilization <em>without the ability to predict the future</em> basically ran out of storage space in their gear-based calendar system.</p><p>I personally am thinking of having an &quot;end of the world&quot; party on December 21st, 2012. I had one on Jan 1, 2000 and I&#39;ll be there laughing at the mindless masses as they cringe in expectation of doomsday. I should be able to pick up some dirt cheap real estate, too.</p>]]></description><category>maya</category><category>2012</category><category>stupidity</category><category>hollywood</category></item><item><title>Something Wicked This Way Comes - Breaking Changes for .NET Services in Azure</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/something_wicked_this_way_comes__breaking_changes_for_net_.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/something_wicked_this_way_comes__breaking_changes_for_net_.htm</link><pubDate>Mon, 02 Nov 2009 13:36:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=something%5Fwicked%5Fthis%5Fway%5Fcomes%5F%5Fbreaking%5Fchanges%5Ffor%5Fnet%5F</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>If you want the full gory details, check out the .NET Services team <a href="http://blogs.msdn.com/netservicesannounce/archive/2009/10/30/the-net-services-november-2009-ctp-breaking-changes-announcement-and-scheduled-maintenance.aspx">blog post here</a>. What follows below are some of the things that I think are most crucial to understand both for new developers and for developers unfortunate enough to be in a position of having to migrate a lot of code. Quite possibly the single most important thing to note is this:</p><blockquote><p><em>If you bought a book on Windows Azure that has already been released or will be released within the next month or two, it is out of date and completely irrelevant. PDC (along with the changes I&#39;m going to outline below) will substantially change all of the Azure offerings.</em></p></blockquote><p>I&#39;ve trimmed a little bit because some of the breaking changes are fairly minor and don&#39;t have too much impact on developers. Here is the list:</p><ul><li>Portal address change. This is an easy enough fix and a simple find-and-replace if you&#39;ve got any code that uses that portal address.</li><li>Solution region migration. Some solutions when migrated to the new version of .NET Services might end up hosted in a different geographical region than before. This isn&#39;t all that big of a deal (for most of us).</li><li><strong>Queues Are Being Removed</strong>. This is <em>huge</em>. In the current version of .NET Services, you can use queues as a way of sending reliable, durable messages between the cloud and on-premise applications without the other endpoint being physically connected. This is a huge change. A new concept called <em>Message Buffers</em> are being introduced. I don&#39;t have all that much information on them but it looks as though the message buffers are essentially transient queues. You send a message to a buffer and it&#39;ll hang out in the buffer while the other end steadily pulls messages out of the buffer. A key point they make is that if you&#39;re looking for durable, reliable, <em>persisted</em> messages between service bus endpoints, you might want to look at using Azure Storage. As painful as it is to see queues go, I think this is a good move. Azure storage already has Queues, and they are robust and powerful. If the reason you were using Queues was to keep from overloading an endpoint with too many messages, the message buffer is your new tool of choice. If you were using Queues so that you could send messages while the polling end was offline, then you&#39;re probably going to need to concoct something involving an Azure Storage queue.</li><li><strong>Routers Are Being Removed</strong>. This is also <em>huge</em>, though slightly less huge than queues. The router concept never really &quot;gelled&quot; with me to begin with - I couldn&#39;t quite figure out how best to use it. Now that they&#39;re being removed and there will be some samples on how to do things like load balancing and targeted delivery, architectural decisions in this area should become easier to make.</li><li>Relay Bindings are now secure (HTTPS) by default. You can override this behavior but there&#39;s very little reason to do so unless you are specifically trying to get your security information stolen.</li><li>Service Namespace. Now instead of the solution name being the hostname of your *.servicebus.windows.net server, you will be able to choose something called the service namespace and have that be the hostname prefix, e.g. (namespace).servicebus.windows.net. This has low impact but is actually very useful.</li><li><strong>TransportClientCredentialType</strong> is being limited. Transport client credentials can no longer include X509 certificates, username/password combinations, or CardSpace cards.</li><li><strong>TcpRelayConnectionMode.Direct</strong> will be removed. This bugs me a little bit because way WAY back when Azure was first unveiled to the public, I remembered talking to someone who said that we&#39;d be able to use the service bus to establish direct connections between two peers both of whom were behind firewalls. This is no longer a possibility, but I can see the reasoning behind it and, quite frankly, my particular use case for this feature was really niche-y.</li><li>Service publishing feed now matches transport. This is handy and makes things a little more straightforward. For those who don&#39;t know, a service publishing feed is basically an Atom feed that shows all of the endpoints on your service bus service that have indicated they want their presence known publicly. In other words, I could hit the service publishing feed and get a list of all connected endpoints. That one ability is <em>ridiculously</em> powerful and is not getting nearly enough hype for the number of scenarios it enables.</li><li>WSHttpRelayBinding has been removed. I&#39;m not gonna miss this one bit as I never used it. </li><li>WS2007FederationHttpRelayBinding removed. Again, not gonna miss it.</li><li><strong>Solution credentials replaced with issuer credentials in Access Control Service</strong>. This one is also quite big. Today, you can use a username/password combo, an X509 cert, or a CardSpace card to <em>request tokens from the STS</em>. As of Thursday, you&#39;re going to need an issuer credential (issuer key and issuer name). In addition, we&#39;re going to have to upload X509 certs to the portal to allow for SAML token requests. I will probably be doing a blog post on this once I get more information because this one is totally game changing and will halt development workflow as it stands now and totally change it after Thursday.</li><li><h2 style="line-height: normal; margin: 10pt 0in 0pt"><font face="Cambria" size="4">WS-Trust STS replaced with Web Resource Authorization Protocol (WRAP) STS</font></h2>&nbsp; - Yes, I made this one gigantic. Why? <em>Ding dong the witch is dead! The wicked witch is dead!</em> WRAP is RESTful people. WS-Trust is EVIL people. Enjoy. We&#39;ve all just been given a shiny cupcake with a frosting of <em>awesome</em> on top.</li><li>Access Control Service data <em><strong>will not be migrated</strong></em>. This means if you&#39;re one of those crazy early adopters and you&#39;ve already written a complete app on the existing ACS - <em>get your data backed up and saved somewhere now. It will be deleted on Thursday morning!</em></li><li>Access Control Management Portal is being replaced with a command-line tool. I know some of you might be thinking, <em>dammit! </em>But I see this as a good thing. It&#39;s an absolute pain in the ass to stop what I&#39;m doing and click through 8 billion links (including the 500,000,000,000,000 redirects involved with a Windows Live ID login) just to go tweak some small setting. I could probably take 20 minutes to rig up a couple .cmd files to do regular ACM tasks that are specific to my app and be done with it. This is going to be a big productivity gain, even though we lose some flashy web-based GUI.</li></ul><p>Here&#39;s the bottom line: </p><p><em>Windows Azure (including Azure Storage, SQL Azure, and .NET Services) is maturing. It is moving away from being an experiment and moving toward a product that can sustain regular income and regular usage and the 90% customer usage scenarios. As a result, they&#39;re going to break changes and add features and shut off lame or ineffective or almost-never-used features.</em></p><p>Can&#39;t wait to get my hands on the new bits Thursday.</p>]]></description><category>pdc09</category><category>azure</category><category>netservices</category><category>cloud</category><category>acs</category><category>servicebus</category></item><item><title>LINQ to SQL and Entity Framework on top of SQL Azure</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/l2s_ef_sqlazure.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/l2s_ef_sqlazure.htm</link><pubDate>Wed, 28 Oct 2009 23:33:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=l2s%5Fef%5Fsqlazure</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>As mentioned in my <a href="/sqlazure_maintenance.htm" target="_blank">previous blog post</a>, you don&#39;t get full designer support on SQL Azure within SQL Server Management Studio. In addition, you don&#39;t get designer support for LINQ to SQL or Entity Framework, either. So what do you do if you want to take advantage of these awesome object mapping tools but the designers don&#39;t work directly against the cloud?</p><p>Conveniently enough, if you follow the tips in the previous blog post, you would have already created a local copy of your SQL Azure database. The &quot;trick&quot; (not really a trick at all, just not immediately obvious) is to point your EF or LINQ to SQL Visual Studio projects at your local database. This will give these mappers the schema and relationship information they need in order to create the appropriate conceptual&lt;-&gt;relational mappings.</p><p>For LINQ to SQL, all you need to do is replace the connection string that it adds to your <em>app.Config</em> file with the connection string supplied by the <em>sql.azure.com</em> portal. Remember to include your password in this connection string because the portal copies a version of this string to your clipboard with the password of <em>myPassword</em>. At this point you should also be thinking to yourself, &quot;<em>Wow, I just put a cleartext password in a .config file. It&#39;s a really good thing that this code isn&#39;t going to sit on someone&#39;s desktop and will be protected in the cloud.</em>&quot; </p><p>With Entity Framework, the connection string is a little more complicated. There&#39;s some entity stuff in there that points to the various model definition files in the project and then there&#39;s an embedded connection string. Replace the embedded connection string (take care to maintain the escaping of nested quotes, etc) with the one the SQL Azure portal supplied and change the password to reflect the right password.</p><p>At this point you should have been able to generate a model from your <em>local</em> database and then change the connection string so that the actual data comes from the <em>cloud</em> database. It might seem a little inconvenient but it isn&#39;t really all that bad. It just adds a few extra steps to your SDLC when you need to change the schema of a live application.</p><p>The feeling I got when I ran my first LINQ to Entities query against a cloud-based SQL Server database was overwhelming. Sure I love new technology as much as the next guy, but the possibilities that are being opened for developers by Windows Azure and cloud computing in general are so numerous it&#39;s hard to contain myself. </p><p>This is a <em>damn good time</em> to be a developer.</p>]]></description><category>sql</category><category>azure</category><category>sqlazure</category><category>entityframework</category><category>linq2sql</category><category>ef</category><category>orm</category></item><item><title>Creating and Manipulating your SQL Azure Database with SSMS and Visual Studio</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/sqlazure_maintenance.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/sqlazure_maintenance.htm</link><pubDate>Wed, 28 Oct 2009 21:31:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=sqlazure%5Fmaintenance</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>So after the long and torturous wait, you&#39;re now in the SQL Azure CTP and you are ready to get the ball rolling with your fabulous, shiny new cloud-based SQL database server. Now what? Well, the first thing you&#39;re going to need to do is create a database.</p><p>To do that, you&#39;ll go to <strong>sql.azure.com</strong> and follow the directions to sign in - if you haven&#39;t already supplied the invite key you&#39;ll need to supply it after you sign in the first time. Select your project and click on it. At this point you&#39;ll see a pretty sparse management screen with two tabs: <em>databases</em> and <em>firewall settings</em>. On the database tab, create a new database (its up to you whether you create a 1GB or a 10GB max database). After you&#39;ve created it, you&#39;ll be able to click the <em>Connection Strings</em> button to get an ADO.NET connection string for the database as well as an ODBC connection string.</p><p>That&#39;s great, but how do you manage the schema? Can you just fire up SQL Server Management Studio (SSMS) and right-click on the &quot;Tables&quot; node and create new tables the old fashioned way? Unfortunately, no. You cannot connect to SQL Azure directly with SSMS the way you can to a regular SQL Server instance.</p><p>To connect to SQL Azure with SSMS:</p><ol><li>Open SSMS (this part should be pretty obvious)</li><li>When you are prompted to connect to a database, <em><strong>cancel that dialog</strong></em>.</li><li>You should be left with an empty management console. Click <em><strong>New Query</strong></em>.</li><li>For the server name, take the fully qualified host name from your SQL Azure connection string. It should look something like <em>(blah).database.windows.net</em>.</li><li>Choose SQL Server Authentication. Supply the username and password that you used for your database. Parts of this information should also be visible on your connection string.</li><li>Click on the <em>Options</em> button on the bottom right of the dialog box</li><li>Set the database name, manually, to the name of your database. It will not show up in the drop-down list.</li><li>Force the network protocol to be TCP/IP (this step may not be necessary, but I do it out of habit)</li><li>Make sure Server type is set to <em>Database engine</em> (this is the default, but might not be if you use SSMS for more than your average bear)</li><li>Now you can click <em>Connect</em>.</li></ol><p>At this point, if everything worked well, you should <em><strong>FAIL</strong></em> to connect to SQL Azure :) You should get some horrid message about a connection from your public IP address not being allowed. This is because this version of SQL Azure has a built-in firewall and, by default, it doesn&#39;t allow anything through.</p><p>Go back to the <em>sql.azure.com</em> portal and click on the <em>Firewall Settings</em> tab. Check the <em>Allow Microsoft Services to Access this server</em> box. Click the button to add a new record. At this point it will conveniently show you what it thinks your public IP is so you can create a new rule to allow your IP through. Keep in mind this is <em>only</em> required to allow your home computer to access your SQL Azure server. If you have checked the <em>Allow Microsoft Services...</em> checkbox, then connections from within the Azure fabric (like an ADO.NET call from inside an ASP.NET app in an Azure Web Role) will pass through the firewall unhindered. This firewall is specifically to keep the communication safe and give you a &quot;DMZ-like&quot; experience where only the people (IPs) you trust will be able to hit that server from outside the Azure cloud fabric.</p><p>Now, after adding the firewall rule, you will <em>need to wait up to 15 minutes or more</em>. When I did it, it took over 20 minutes. The reason is that the portal where you hit the submit button is not the same physical machine as your SQL Azure server. It takes a few minutes for your new firewall rule to make it over to the actual data center where your SQL Azure server has been provisioned (at least that&#39;s my best guess to explain this delay). So don&#39;t be alarmed if 10 seconds after you add the firewall rule you still can&#39;t get into your database.</p><p>Now you are free to write T-SQL until you are blue in the face. What&#39;s that, you don&#39;t love hand-writing T-SQL schema change scripts without any assistance from an IDE? Neither do I. This is why I created a Visual Studio 2008 &quot;Database Project&quot; that references a <em>local database with the same schema as the one I want to have in the cloud</em>. This is useful for multiple reasons. The biggest of which is that with a &quot;Database project&quot; I can version control my scripts. Secondly, I automatically gain the benefit of a local development copy of my database. Finally, this allows me to, from within VS, right-click any schema element and script it into the project. I can then open that script, <em>do some cleaning up</em>, and then execute that script in the aforementioned SSMS query window. The <em>cleaning up</em> I&#39;m referring to means stripping out the plethora of extraneous options on the ends of the <em>CREATE TABLE</em> statements and things like that. A lot of those options aren&#39;t available in SQL Azure so just strip them out after you script the table, proc, view, whatever. It&#39;s a pain in the butt, but it&#39;s certainly better than having to hand-craft all that T-SQL if you aren&#39;t into that sort of thing. I know some developers that like to get all kinky with their T-SQL and would never let VS script it for them. Me, I like to wear protective gear when I talk to the database schema so letting VS give me a head start <em>suggestion</em> as to the script I should run on SQL Azure works just fine for me.</p>]]></description><category>sql</category><category>azure</category><category>sqlazure</category><category>visualstudio</category><category>cloud</category><category>database</category></item><item><title>Client-Side Validation with jQuery, DataAnnotations, MVC 2, and VS2010 Beta 2</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/clientvalidation_mvc2.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/clientvalidation_mvc2.htm</link><pubDate>Mon, 26 Oct 2009 13:58:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=clientvalidation%5Fmvc2</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Anytime a feature of a framework gives me something for free that I don&#39;t need to manually implement I&#39;m a happy camper. One such feature of ASP.NET MVC 2 is jQuery client-side validation. The reason I like this is that unlike other jQuery frameworks, where you have to write the jQuery yourself - you don&#39;t need to do that with MVC 2. </p><p>Instead of having to maintain simple validation logic in two places (your business classes and your jQuery code), you can now use the Data Annotations attributes and metadata &quot;buddy&quot; classes to decorate your models. Those decorated models will <em>automatically</em> generate the appropriate jQuery code to enforce all of your validation rules on the client side before the form is ever submitted. Let&#39;s see how this works.</p><p>First, we need a model class. Let&#39;s do something simple like Customer:</p><pre>public partial class Customer<br />{<br />&nbsp;&nbsp;&nbsp; public string Name { get; set; }<br />&nbsp;&nbsp;&nbsp; public int Age { get; set; }<br />}</pre><p>This is great. I love the fact that it doesn&#39;t look ugly and view developers can look at it and immediately know what fields are available and they don&#39;t need to sift through a pile of persistence garbage or validation logic. You might have noticed that I&#39;ve made this class partial. The reason I&#39;m doing this is because I&#39;m going to create another file called <strong>Customer.metadata.cs</strong>. There are other samples on the web that don&#39;t do this, but I like cleanly separating the <em>definition </em>of my model from the <em>validation logic</em> for that model. Here&#39;s a look at my Customer.metadata.cs file:</p><pre>[MetadataType(typeof(CustomerMetaData))]<br />public partial class Customer<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;class CustomerMetaData<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [Required(ErrorMessage=&quot;You must supply a name for a&nbsp;customer.&quot;)]<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [StringLength(50, ErrorMessage = &quot;A customer name cannot exceed 50 characters.&quot;)]<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public string Name { get; set; }<br />&nbsp;&nbsp;&nbsp; }<br />}</pre><p>What I&#39;ve done here is used a metadata &quot;buddy class&quot; (that&#39;s what posts from Scott Guthrie and Scott Hanselman have been calling them, so I&#39;m sticking with convention here). This buddy class is a placeholder for all my validation logic attributes and the runtime will then merge all this stuff onto the actual model. MVC 2 will then examine the model and , with a few lines of code in the view, generate the appropriate jQuery client-side validation logic.</p><p>In your view code, add the following 3 script declarations:</p><font face="Consolas" size="2"><font face="Consolas" size="2"><p><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">&lt;</font></font></font><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000">script</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000">type</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">=&quot;text/javascript&quot;</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000">src</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">=&quot;../../Scripts/jquery-1.3.2.min.js&quot;&gt;&lt;/</font></font></font><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000">script</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">&gt;<br /></font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">&lt;</font></font></font><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000">script</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000">type</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">=&quot;text/javascript&quot;</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000">src</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">=&quot;../../Scripts/jquery.validate.min.js&quot;&gt;&lt;/</font></font></font><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000">script</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">&gt;<br /></font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">&lt;</font></font></font><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000">script</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000">type</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">=&quot;text/javascript&quot;</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000"><font face="Consolas" size="2" color="#ff0000">src</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">=&quot;../../Scripts/MicrosoftMvcJQueryValidation.js&quot;&gt;&lt;/</font></font></font><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000"><font face="Consolas" size="2" color="#800000">script</font></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">&gt;</font></font></font></p></font></font><p>Finally, somewhere before the start of your form tag, add the following markup to the view code:</p><pre>&lt;% Html.EnableClientValidation(); %&gt;&nbsp;</pre><p>This will invoke the code that reads through the strongly typed model for your view, figures out all of the validation logic that applies, and generates the appropriate jQuery code.</p><p>While you could write your own jQuery validation code if you felt like it, using data annotations and MVC 2, you no longer have to maintain your validation logic in two places. The attributes apply to a single view model and all you have to do is change one of those attributes and the generated jQuery code will change as well. This is a <em>huge</em> timesaver and promises to dramatically increase overall productivity of developers building large-scale MVC 2 applications, especially LOB apps with lots of data entry forms.</p><p>&nbsp;</p>]]></description><category>vs2010</category><category>mvc2</category><category>jquery</category><category>dataannotations</category><category>validation</category><category>client</category><category>mvc</category><category>aspnet</category></item><item><title>Templated Helpers in ASP.NET MVC 2 (VS2010 Beta 2 Version)</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/mvc2_templated_helpers.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/mvc2_templated_helpers.htm</link><pubDate>Thu, 22 Oct 2009 12:21:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=mvc2%5Ftemplated%5Fhelpers</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Templated Helpers are one of the new features in ASP.NET MVC 2. The other day, Visual Studio 2010 Beta 2 came out and some of you may have noticed that it comes pre-equipped with a beta release of ASP.NET MVC 2. In short a templated helper is a way of using various combinations of implicit and explicit rules to automatically place partial controls wherever particular data types need to appear, either in edit mode or display mode.</p><p>So let&#39;s say you have a DateTime property on your model called MeetingDate. Rather than make every single view write its own (potentially contrasting!) code to render dates in view mode and in edit mode, you can now do something like this:</p><pre>&lt;%= Html.DisplayFor( m =&gt; m.MeetingDate ) %&gt;<br />&lt;%= Html.EditorFor( m=&gt; m.MeetingDate) %&gt;</pre><p>The <em>DisplayFor</em> helper will look at the data type of the thing you&#39;re looking for and try and figure out how to render that item. If you don&#39;t override convention, it will look in the <em>Shared/DisplayTemplates</em> folder for a <em>DateTime.ascx</em> control. If you want the display template to be specific to a certain controller, it can also look under the <em>Views/(ControllerName)/DisplayTemplates</em> folder. This same rule applies to <em>EditorFor</em>. It will look for the special <em>EditorTemplates</em> folder to try and find a suitable control. By &quot;control&quot; here I&#39;m actually referring to a <em>partial view</em> since technically there are no controls in the traditional ASP.NET sense in MVC.</p><p>There&#39;s another HTML helper that you can use in your top-level view to invoke the partial-view location heuristics for an entire model just by doing:</p><pre>&lt;%= Html.EditorForModel () %&gt;</pre><p>This will examine the data type of your strongly-typed view and go look in an <em>EditorTemplates</em> folder to find the appropriate partial view.</p><p>Finally, there&#39;s another way you can supply hints to the templated helper system. That&#39;s through the use of the <em>UIHint</em> attribute. The UIHint actually allows you to decorate your view model (you are using an isolated view model and not working against persistance objects directly, aren&#39;t you?) with hints as to which editor should be used. This is <em>fantastic</em> for drop-down lists because the underlying value of a dropdown list is usually the ID of the lookup column, which is just an Int. You can&#39;t infer from Int that you want the Country dropdown vs. the State dropdown vs. the Weapons dropdown. To tell the engine which template you want, you can use the UIHint attribute as follows:</p><pre>[UIHint(&quot;CustomerStatusDropDown&quot;)]<br />public CustomerStatus CustomerStatus { get; set; }</pre><p>Where CustomerStatus is another view model object that you&#39;ve got with a Name/ID pair (In my case I did it this way to accomodate the data coming from an ADO.NET Data Service). When you do <em>Html.DisplayFor</em> on this particular property of this particular class, it will override the normal algorithm and go look for a <em>DisplayTemplate</em> called <em>CustomerStatusDropdown.ascx</em>. When you do <em>Html.EditorFor</em>, it will look for a file called <em>CustomerStatusDropDown.ascx</em> but in the <em>EditorTemplate</em>s directory. This allows you to simply, cleanly, and elegantly control how you display and edit lookups. </p><p>If you want, you can control the template selection directly from the EditorFor method call:</p><pre>&lt;%= Html.EditorFor ( cust =&gt; cust.BirthDate, &quot;DateTime_jQuery&quot;) %&gt;</pre><p>You might use a pattern like this in order to allow some pages to edit date/times with a jQuery picker instead of a traditional date/time picker. The possibilities are endless.</p><p>The reason why I&#39;m blogging about this now, only a few days after Beta 2 comes out, is because I think this way of arranging your UI is <em>so, absolutely, positively</em> crucial to a clean, elegant, easy to maintain ASP.NET MVC application that everybody should be getting in the habit of using templated helpers now so that by the time VS 2010 hits RTM, the use of templated helpers will be old hat and we&#39;ll all be one step closer to ridding the world of &quot;tag soup&quot; forever.</p><p>p.s. If you invoke some of these EditorFor and DisplayFor helpers without actually having a suitable control in the EditorTemplates or DisplayTemplates directory, you might find some pretty interesting results. For example, if you do EditorForModel, and there isn&#39;t a control for that data type in your <em>EditorTemplates</em> directory, the system will actually use Reflection. It will sift through the public properties of your model, and for each property it will do the equivalent of invoking <em>EditorFor</em> and <em>LabelFor</em> on that property. In short, it will scaffold you up a &quot;best guess&quot; editor for your entire object. The reason this is in a &quot;p.s.&quot; is because such scaffolding is great for smoke testing, but rarely lasts long.</p>]]></description><category>vs2010</category><category>beta</category><category>mvc</category><category>mvc2</category><category>template</category><category>controls</category><category>ui</category><category>jquery</category></item><item><title>Kindle 2 vs. Nook</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/kindle_vs_nook.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/kindle_vs_nook.htm</link><pubDate>Wed, 21 Oct 2009 01:59:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=kindle%5Fvs%5Fnook</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[Barnes and Noble just recently unveiled their upcoming eReader, the Nook. On the blog of my non-techy alter-ego I&#39;ve posted a comparison of the two readers that is entirely based on my own personal feelings of what is cool and what isn&#39;t, so take it as opinion and certainly not as a technical review. <strong><a href="http://tinyurl.com/yjfyzcm">Click here</a></strong> to check out the blog post.]]></description><category>ereader</category><category>ebooks</category><category>kindle</category><category>nook</category><category>amazon</category><category>barnesandnoble</category></item><item><title>Get Your Red Hot VS2010 Beta 2!</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/vs2010_beta2_release.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/vs2010_beta2_release.htm</link><pubDate>Mon, 19 Oct 2009 20:43:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=vs2010%5Fbeta2%5Frelease</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Visual Studio 2010 Beta 2 is now available to MSDN subscribers and will be available to the public at large late next week. The list of stuff that is awesome and worth checking out in VS2010 Beta 2 is too long and ridiculously in-depth for me to cover here. Some of the big things that affect me right off the bat are the following:</p><ul><li><strong>ASP.NET MVC 2</strong> is now built right into the installation. Finally we get convergence of the ASP.NET MVC project and VS2010 tools. Up until now, MVC 2 was only working on VS2008 which sucked for us early adopters of VS2010 and MVC!</li><li>Azure Tools - there&#39;s a project type in here that when you create a new project of this type (&quot;Cloud Service&quot;) it tells you how to get going with Azure. Current versions of Azure only run on .NET Framework 3.5 SP1 and right now I have enough available virtualization and memory to not mingle. So right now, I&#39;m not going to even bother trying to get Azure working on VS2010 until I know the Azure back-end is running .NET Framework 4 and there is native, in-IDE tooling for VS2010 like there is for VS2008.</li><li><strong>EF4</strong> - All kinds of ridiculous stuff here. Be sure to check out the Entity Framework blog for information on what&#39;s new in Beta 2.</li><li><strong>WCF and WF</strong> - Workflow services, Workflow in general, and WCF overall have recieved quite a bit of overhauling and fine tuning since beta 1. Make sure you try workflow services with content-based correlation and service discovery - all very awesome stuff.</li><li><strong>Astoria with Projections</strong> - the same goodness that you&#39;ve been enjoying with the 1.5 CTP2 of Astoria (including projections!!) is available already inside VS2010.</li></ul><p>As I said, there are a billion other things available in VS2010 Beta 2 and there are a billion other blogs that have more detailed information on it so I&#39;m not going to duplicate that stuff here.</p><p>Bottom line is this: Go grab VS2010 from your MSDN subscription <em>now</em>, or wait until they release it to the public during PDC. Start messing with it and start playing with it.</p>]]></description><category>pdc</category><category>vs2010</category><category>beta</category></item><item><title>The Origin of Stupidity</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/origin_of_stupidity.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/origin_of_stupidity.htm</link><pubDate>Wed, 14 Oct 2009 13:01:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=origin%5Fof%5Fstupidity</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>So apparently Kirk Cameron and a buddy of his are continuing their campaign of lies and outright stupidity because things like common sense, science, and cold hard fact threaten their fragile hold on sanity. Ordinarily I might on on a huge rant about this but everything I could say, the woman in this video says much more eloquently than I could. This is a must-watch.</p><p>&nbsp;</p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="445" height="364"><param name="movie" value="http://www.youtube.com/v/fmHN3JtyUXg&amp;hl=en&amp;fs=1&amp;rel=0&amp;border=1" /><param name="quality" value="high" /><param name="menu" value="false" /><param name="wmode" value="" /><embed src="http://www.youtube.com/v/fmHN3JtyUXg&amp;hl=en&amp;fs=1&amp;rel=0&amp;border=1" wmode="" quality="high" menu="false" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="445" height="364"></embed></object>]]></description><category>kirkcameron</category><category>atheism</category><category>evolution</category><category>darwin</category><category>humor</category></item><item><title>ADO.NET Data Services Projections Makes Sliced Bread Jealous</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/astoria_projections.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/astoria_projections.htm</link><pubDate>Fri, 09 Oct 2009 15:07:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=astoria%5Fprojections</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>The other day I ran into a blog entry from the Astoria team discussing the <em>projections</em> feature of the 1.5 CTP2 version of the product. If you&#39;re not familiar with ADO.NET Data Services (formerly codenamed <em>Astoria</em>), it&#39;s basically a layer that you can put on top of an Entity Data Model and it will expose that model as a RESTful service. The URL format for this RESTful service is quite flexible, allowing you to select individual rows, perform filters, sorts, and many other things.</p><p>One of the new things that you can now do server-side via the new CTP2 URL syntax is projections. Projections actually allow you to control the shape of the output coming back. You can specifically choose which properties on the entity you want. Even more awesome is that this can be controller hierarchically. So if you bring back an Order entity and you include all of the OrderItem entities for that order, you can tell the server that you only want the customer for the Order and you only want Quantity and Price for the order items.</p><p>To perform a projection on the URL, you just use the $select parameter, like this:</p><pre>blah.svc/Orders?$select=OrderID,Quantity,Price</pre><p>And to control the shape of hierarchical data:</p><pre>blah.svc/Orders?$select=OrderID,Quantity,OrderItems/Price,OrderItems/Quantity&amp;$expand=OrderItems</pre><p>At this point when I saw this I started having convulsions of pure joy. The main reasons being that every ADO.NET Data Services URL query will output either AtomPub or JSON. This means I can get only the columns I need and give them to my Ajax calls. Then I noticed that support for the new projections is actually in the Astoria client library as well, allowing me to write the following query:</p><pre>var q = from order in ctx.Orders<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where order.Price &gt; 300<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderby order.Price descending<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select new { Price = order.Price, Quantity = order.Quantity };</pre><p>This will translate into an Astoria query that filters, sorts, AND projects all on the server side, leaving me with a network footprint that only transmits the information I want and nothing else. This is a godsend if you have entities with huge amounts of columns but each individual query might only need to use 1 or 2 of those columns at a time.</p><p>And now, if this wasn&#39;t ridiculous enough, you can actually perform updates using the projected objects, AND those updates will ONLY transmit the information necessary. For example, if I only want to change an order&#39;s price and I got the price from a projection, I don&#39;t need to carry the entire order payload across the wire in order to commit the change:</p><pre>order = q.First();<br />order.Quantity = order.Quantity + 42;<br />svc.UpdateObject(order);<br />svc.SaveChanges();</pre><p>This will figure out that the only thing changing is the Quantity field and it will ONLY send that information. After discovering the combination of projections and the efficient round-trips of Astoria, this is when my head exploded.</p><p>If you have a multi-tier scenario and you&#39;re using an Entity Data Model (EDM), then you should definitely look into using ADO.NET Data Services to expose that model via services because now with projections, you can really do some unbelievable stuff. All that garbage code you used to have to generate to convert between DTOs and ViewModels and Entities and back again? You can delete ALL of that crap.</p><p>I&#39;ve said it before but the folks working on ADO.NET Data Services deserve a medal. If you see a member of that team, buy them a beer. You have no idea how ridiculously complicated and difficult it is to write code that supports arbitrary projections like this. I&#39;m pretty sure every time you run an Astoria query with projections, an Angel gets its wings.</p>]]></description><category>astoria</category><category>adonet</category><category>dataservices</category><category>data</category><category>entityframework</category><category>projections</category></item><item><title>Using ASP.NET MVC Action Filters to Declare Reference Data for Views</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/aspnet_actionfilter_referencedata.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/aspnet_actionfilter_referencedata.htm</link><pubDate>Fri, 02 Oct 2009 16:17:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=aspnet%5Factionfilter%5Freferencedata</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>When we all build websites, usually we&#39;re concerned with figuring out how we&#39;re going to get the major entities into the view. We want to know how we&#39;re going to handle the shopping cart or how we&#39;re going to get the customer record onto the page, etc. But, one of the little details that almost always comes back to bite us in the ass is the use of <em>reference data</em>.</p><p><em>Reference data</em> is data that rarely changes, is frequently queried, and shows up in multiple places throughout the application. This might be anything from the list of companies currently trading on a particular stock market if you&#39;re building a financial web application or things like the list of countries, states, cities, counties, tax rules, and shipping tables if you&#39;re doing fulfillment of orders online.</p><p>The problem is we rarely think about reference data ahead of time, so what usually happens is our strategy for handling reference data becomes an ugly pile of spaghetti and we have some controls doing their own queries to get reference data and some pages doing it and some services - it&#39;s a mess.</p><p>It would be awesome if we could have our controller methods declare ahead of time what reference data the view is going to need and then the view will simply have that data when it renders - completely abstracting the manual fetching of reference data for dropdownlists and other lookups. This centralization of reference data handling also gives us the ability to control the cache lifetimes of reference data items individually.</p><p>Thankfully ASP.NET MVC lets us do this easily. All we have to do is create our own action filter attribute. For example, let&#39;s say we&#39;ve got a Customer controller and we&#39;re building the <em>Edit(int id)</em> method. Our customer view model objects are normalized enough so that they have IDs on them for country, customer type, and membership type (totally contrived examples, don&#39;t diss my domain knowledge of CRMs...). A sample edit method might look like this:</p><pre>[RequireReferenceData(ReferenceDataKey = ReferenceDataKeys.Countries)]<br />[RequireReferenceData(ReferenceDataKey = ReferenceDataKeys.CustomerTypes)]<br />[ReqiureReferenceData(ReferenceDataKey = ReferenceDataKeys.MembershipTypes)]<br />public ActionResult Edit(int id)<br />{<br />&nbsp;&nbsp;&nbsp; Customer cust = customerRepository.GetCustomerByKey(id);<br />&nbsp;&nbsp;&nbsp; return View(cust);<br />}</pre><p>The beauty of this approach is that <em>anyone</em> reading your code will <em>immediately </em>know that the view being rendered is going to depend on having 3 different types of reference data lists made available, as well as the core <em>Customer</em> object itself. Compare how easy this is to read and maintain to a classic .ASPX page where you might have the countries lookup being loaded by a custom dropdown box and the customer types lookup being loaded by the page and the membership types being loaded by yet another pile of spaghetti elsewhere.</p><p>To create the RequireReferenceDataAttribute class, all you need to do is inherit from ActionFilterAttribute and override the OnExecuting method. In this method you would just fetch the reference data and store it in the ViewData dictionary like this:</p><pre>context.Controller.Model.ViewData[ReferenceDataKey] = (data fetched from elsewhere...);</pre><p>And then in your view you can do something like this:</p><pre>&lt;%= Html.DropDownList(&quot;CustomerTypeId&quot;,&nbsp;<br />(IEnumerable&lt;SelectListItem&gt;)ViewData[ReferenceDataKeys.CustomerTypes]) %&gt;</pre><p>And you&#39;re all set. The main moral of this story is to never underestimate the power of action filters. With ASP.NET MVC, if you want your intent to be more declarative and you want your code to be more readable, chances are you&#39;re only a few lines of code away from where you want to be.</p>]]></description><category>aspnet</category><category>mvc</category><category>actionfilter</category><category>referencedata</category></item><item><title>Creating Correlated Workflow Services in WF4 / .NET4 : Part 1</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/corr_wfservices1.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/corr_wfservices1.htm</link><pubDate>Wed, 30 Sep 2009 14:02:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=corr%5Fwfservices1</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>In the past, Windows Workflow Foundation hasn&#39;t gotten a (deservedly so) bad reputation for being full of needless bloat, overly complicated, and missing a lot of key things that make workflow productive for developers. As a result of that, Microsoft completely overhauled WF in the .NET Framework 4.0. One of the new features of WF4 is the concept of a <em>workflow service</em>. A workflow service is really nothing more than a workflow that is hosting WCF endpoints within the activity. This allows the workflow to progress from start to finish by communicating with external clients, such as websites, WPF applications, or Silverlight applications.</p><p>In the sample I&#39;m going to illustrate in this series of blog posts, I&#39;m going to create a customer service helpdesk application. There will be a single workflow at the core of the application - the customer issue workflow. A customer calls complaining that their widget is completely, horribly broken and the customer service rep starts a new issue. The issue then persists forever while communciation goes back and forth between the customer until finally one of the communication types is a &quot;close ticket&quot; type. This is a really simple workflow, but should be similar enough to things that people do in the &quot;real world&quot; that the sample won&#39;t feel contrived or too &quot;hello world&quot;-ish.</p><p>Some of the stuff that I&#39;ll be showing here will look very similar to the WCF/WF 4 Training Kit. The main issue I have with that training kit is that there&#39;s too much &quot;magic&quot; in it. By &quot;magic&quot; I mean stuff that was pre-created for you (like service references consuming the workflow services), so in this sample I&#39;ll walk you through how to create all that magic.</p><p>So to get started let&#39;s create a Sequential workflow and host it in a console app. I would normally host it inside IIS but I couldn&#39;t figure out how to get the HTTP metadata exchange stuff to be published on the .xamlx endpoint. To do this, open up Visual Studio 2010 Beta 1 and create a new project of type <strong>Sequential Workflow Console Application</strong>. Delete the Sequence1.xaml file and add a new sequential workflow to the project called <strong>SupportCall.xaml</strong>. From the toolbar, drag over a <strong>ReceiveAndSendReply</strong> activity from the <strong>Messaging</strong> category. This is the activity that is going to allow your workflow to receive a message via WCF and then do something with it.</p><p>Before we can do something with the message, we need to know what the message looks like. To do that, I added a class library to the solution and created a data contract class that looks like this:</p><p><font face="Consolas" size="2"><font face="Consolas" size="2">[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataContract</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">class</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">Customer<br /></font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">{<br />[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataMember</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">string</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> FirstName { </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">get</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">set</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; }</font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> <br />[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataMember</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">string</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> LastName { </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">get</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">set</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; }<br />[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataMember</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">string</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> CustomerID { </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">get</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">set</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; }</font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> <br />[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataMember</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">string</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> Address1 { </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">get</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">set</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; }<br />[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataMember</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">string</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> Address2 { </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">get</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">set</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; }</font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> <br />[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataMember</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">string</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> City { </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">get</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">set</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; }<br /></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataMember</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">string</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> State { </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">get</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">set</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; }</font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> <br />[</font></font><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af"><font face="Consolas" size="2" color="#2b91af">DataMember</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">]<br /></font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">public</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">string</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> Zip { </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">get</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; </font></font><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff"><font face="Consolas" size="2" color="#0000ff">set</font></font></font><font face="Consolas" size="2"><font face="Consolas" size="2">; }</font></font><font face="Consolas" size="2"><font face="Consolas" size="2"> <br />}</font></font></p><p>Add a reference to the contracts assembly from your workflow project and build the solution. Now you can modify the messaging piece of your workflow to accept messages of type <strong>Customer</strong>. To do this, you need to add a <em>variable</em> to the workflow.</p><p>Click the &quot;Variables&quot; button on the bottom left of the workflow designer surface and add a new variable named <strong>CurrentCustomer</strong>. When you choose the data type, click &quot;Browse&quot; and then type &quot;Customer&quot;, you should find under the &quot;Referenced Assemblies&quot; tree node the customer class from the contracts assembly. When you&#39;ve created this variable, your variables area should look something like this:</p><p><img src="http://files.blog-city.com/files/J05/88284/p/f/wf4_seq0.png" alt="" width="749" height="173" /></p><p>In order to receive data from a message, you need somewhere to put that data. In a workflow service, that somewhere is a variable. Now you can go and click on the Receive-Reply sequence and edit it so that the operation name is <strong>StartIssue</strong>, the service contract name is <strong>CustomerIssueService</strong> and the <em>Value</em> property (where the message value is stored) is the name of the variable we just created: <strong>CurrentCustomer</strong>. When you&#39;re done editing the receive-sendreply sequence, it should look something like this:</p><p><img src="http://files.blog-city.com/files/J05/88284/p/f/wf4_seq1.png" alt="" width="371" height="512" /></p><p>I modified the sendreply portion of the sequence and set the value to the following:</p><pre>&quot;A new issue has been created for &quot; + CurrentCustomer.FirstName + &quot; &quot; + CurrentCustomer.LastName</pre><p>If you&#39;re curious, the syntax for rules and expressions inside WF4 is ... *drumroll* ... <strong>Visual Basic!! </strong>This is important to keep in mind if you&#39;re in there editing rules and the rest of your application is written in C# - your stuff won&#39;t work if you start throwing C# syntax into the expression editors.</p><p>We&#39;re almost there. At this point we now have a workflow, but our solution won&#39;t compile because our <strong>Program.cs</strong> file from the stock VS template is full of junk related to launching <strong>Sequence1.xaml</strong>. Modify your <strong>Program.cs</strong> file to look like this:</p><pre>namespace CustomerSupport.Services<br />{<br />&nbsp;&nbsp;&nbsp; using System;<br />&nbsp;&nbsp;&nbsp; using System.Linq;<br />&nbsp;&nbsp;&nbsp; using System.Threading;<br />&nbsp;&nbsp;&nbsp; using System.Activities;<br />&nbsp;&nbsp;&nbsp; using System.Activities.Statements;<br />&nbsp;&nbsp;&nbsp; using System.ServiceModel.Activities;<br />&nbsp;&nbsp;&nbsp; using System.ServiceModel.Description;<br /><br /><br />&nbsp;&nbsp;&nbsp; <br />    class Program<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void Main(string[] args)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string baseAddress = http://localhost:8081/SupportCall;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />            using (WorkflowServiceHost host = <br />              new WorkflowServiceHost(typeof(SupportCall), new Uri(baseAddress)))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host.AddDefaultEndpoints();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />                host.Open();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;Customer Support Service listening at: &quot; + <br />                  baseAddress);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&quot;Press ENTER to exit&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.ReadLine();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host.Close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</pre><p>Now we should be able to compile and when we run our console application (requires VS to be elevated!) we should see the message indicating that customer support service is running. We can quit the app now.</p><p>To create the client (we&#39;ll be making a better client in future blog posts) let&#39;s just create a new console application and add a reference to the contracts assembly. In order to add a service reference to the workflow service, you have to launch the workflow service console app from the command prompt because you can&#39;t add service references while Visual Studio is currently debugging something. </p><p>Modify the Program.cs for the client console application (after adding a service reference) to look like this:</p><pre>static void Main(string[] args)<br />{<br />&nbsp;&nbsp;&nbsp; CustomerIssueService.CustomerIssueServiceClient svc = <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new CustomerSupport.Client.CustomerIssueService.CustomerIssueServiceClient();</pre><pre>&nbsp;&nbsp;&nbsp; Customer cust = new Customer();<br />&nbsp;&nbsp;&nbsp; cust.FirstName = &quot;Bob&quot;;<br />&nbsp;&nbsp;&nbsp; cust.LastName = &quot;Asdf&quot;;<br />&nbsp;&nbsp;&nbsp; cust.Address1 = &quot;666 Evil Lane&quot;;<br />&nbsp;&nbsp;&nbsp; cust.Address2 = &quot;&quot;;<br />&nbsp;&nbsp;&nbsp; cust.City = &quot;Hades&quot;;<br />&nbsp;&nbsp;&nbsp; cust.State = &quot;NJ&quot;;<br />&nbsp;&nbsp;&nbsp; cust.Zip = &quot;99999&quot;;<br />&nbsp;&nbsp;&nbsp; cust.CustomerID = &quot;ASDF&quot;;<br />&nbsp;&nbsp;&nbsp; string response = svc.<strong><em>StartIssue</em></strong>(cust);<br />&nbsp;&nbsp;&nbsp; Console.WriteLine(response);<br />&nbsp;&nbsp;&nbsp; Console.ReadLine();<br />}</pre><p>Now you can run the application and you&#39;ll see a line of text indicating that a new issue has been created for customer <em>Bob Asdf</em>. In the next blog post, I&#39;m going to walk through adding more steps to the workflow to make it more realistic, including adding another web service call in the same service that uses <em>correlation</em> so that we can progress multiple instances of multiple workflows and correlate the messages to the right workflows based on message content.</p><p>Some things to keep in mind as you wait eagerly for the next blog post are how the naming of the service contract and operation name affect the names of the methods and proxies created when you add a service reference to the workflow service.</p>]]></description><category>wf4</category><category>workflow</category><category>net4</category><category>wcf</category><category>services</category><category>correlation</category></item><item><title>How to Build your First Azure-Powered MVC App</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/how_to_build_your_first_azurepowered_mvc_app.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/how_to_build_your_first_azurepowered_mvc_app.htm</link><pubDate>Tue, 29 Sep 2009 14:16:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=how%5Fto%5Fbuild%5Fyour%5Ffirst%5Fazurepowered%5Fmvc%5Fapp</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>A good friend and colleague of mine has put up a great tutorial that walks you through the process of creating a new &quot;classic&quot; ASP.NET Azure web application and converting it into a cloud-based MVC application. In addition, he shows you how to point your membership, profile, and role providers at Azure cloud storage instead of the default SQL Express. Great read, check it out here:</p><p><a href="http://www.caffeinedi.com/2009/09/29/how-to-build-your-first-azure-powered-asp-net-mvc-app/">http://www.caffeinedi.com/2009/09/29/how-to-build-your-first-azure-powered-asp-net-mvc-app/</a></p>]]></description><category>mvc</category><category>aspnet</category><category>cloud</category><category>azure</category></item><item><title>Binary Serialization and Azure Web Applications</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/azure_binaryserialization.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/azure_binaryserialization.htm</link><pubDate>Tue, 29 Sep 2009 00:54:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=azure%5Fbinaryserialization</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>You might be thinking, <em>pfft, I&#39;m never going to need to use Binary Serialization...that&#39;s old school</em>. And you might be right, but think about this: Azure Storage charges you by how much you&#39;re storing and some aspects of Azure also charge you based on the bandwidth consumed. Do you want to store/transmit a big-ass bloated pile of XML or do you want to store/transmit a condensed binary serialization of your object graph?</p><p>I&#39;m using Blob and Queue storage for several things and I&#39;ve actually got a couple of projects going right now where I&#39;m using binary serialization for both Blobs and Queue messages. The problem shows up when you try and use the <strong>BinaryFormatter</strong> class&#39; Serialize method. This method requires the <em>Security</em> privilege, which your code doesn&#39;t have when its running in the default Azure configuration.</p>So how do you fix this problem so that you can successfully serialize/deserialize binary object graphs and maybe save a buck or two? Easy! Turn on full-trust in your service definition for whichever role is going to be using the binary serialization (in my case both my worker and web roles will be using it...). To do this, open up your service definition file and look for the line that looks like this:&nbsp;<font size="2" color="#0000ff"><font size="2" color="#0000ff"></font></font><font size="2" color="#0000ff"><font size="2" color="#0000ff"> <p>&lt;<font size="2" color="#a31515"><font size="2" color="#a31515">WebRole</font></font><font size="2" color="#0000ff"><font size="2" color="#0000ff"> </font></font><font size="2" color="#ff0000"><font size="2" color="#ff0000">name</font></font><font size="2" color="#0000ff"><font size="2" color="#0000ff">=</font></font><font size="2">&quot;</font><font size="2" color="#0000ff"><font size="2" color="#0000ff">Foo.Web</font></font><font size="2">&quot;</font><font size="2" color="#0000ff"><font size="2" color="#0000ff"> </font></font><font size="2" color="#ff0000"><font size="2" color="#ff0000">enableNativeCodeExecution</font></font><font size="2" color="#0000ff"><font size="2" color="#0000ff">=</font></font><font size="2">&quot;</font><font size="2" color="#0000ff"><font size="2" color="#0000ff"><strong>false</strong></font></font><font size="2">&quot;</font><font size="2" color="#0000ff"><font size="2" color="#0000ff">&gt;</font></font></p></font></font><p>And change it to this:</p><font size="2" color="#0000ff"><font size="2" color="#0000ff"><p>&lt;<font size="2" color="#a31515"><font size="2" color="#a31515">WebRole</font></font><font size="2" color="#0000ff"><font size="2" color="#0000ff"> </font></font><font size="2" color="#ff0000"><font size="2" color="#ff0000">name</font></font><font size="2" color="#0000ff"><font size="2" color="#0000ff">=</font></font><font size="2">&quot;</font><font size="2" color="#0000ff"><font size="2" color="#0000ff">Foo.Web</font></font><font size="2">&quot;</font><font size="2" color="#0000ff"><font size="2" color="#0000ff"> </font></font><font size="2" color="#ff0000"><font size="2" color="#ff0000">enableNativeCodeExecution</font></font><font size="2" color="#0000ff"><font size="2" color="#0000ff">=</font></font><font size="2">&quot;</font><font size="2" color="#0000ff"><font size="2" color="#0000ff"><strong>true</strong></font></font><font size="2">&quot;</font><font size="2" color="#0000ff"><font size="2" color="#0000ff">&gt;</font></font></p></font></font><p>You&#39;ll have to do this for your WorkerRole as well if you want your worker role to be able to do this kind of serialization.&nbsp;That&#39;s it...Now when you run your application it will have sufficient privileges to perform the serialization/deserialization to keep your storage and transmission payloads as small as possible.</p>]]></description><category>azure</category><category>table</category><category>queue</category><category>blob</category><category>storage</category><category>binary</category><category>serialization</category></item><item><title>ASP.NET Membership Provider in the Cloud : The Chicken and the Egg Problem</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/aspnet_cloud_membership.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/aspnet_cloud_membership.htm</link><pubDate>Mon, 28 Sep 2009 15:22:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=aspnet%5Fcloud%5Fmembership</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Let&#39;s take a look at this pretty common scenario. You&#39;re building an ASP.NET application (MVC or otherwise) and you intend to publish it in the cloud and you&#39;re using Azure Storage (not SQL Azure) for your underlying data store. You&#39;ve already hooked your app up with the sample Azure-based Membership provider that comes with the Azure SDK and everything is running along nicely.</p><p>Your application has quite a bit of administrator-only functionality so, after you&#39;ve been using it locally for a while you put in some safeguards to block access to the admin areas unless the user is in the <em>Administrators</em> role. That&#39;s awesome and ASP.NET and ASP.NET MVC both have some really great code shortcuts for enabling this kind of situation and you can make yourself an administrator pretty darn easily.</p><p>So you&#39;re an admin and you deploy your application to staging and you go to run it and you try to log in. <em>Whoops</em> your account isn&#39;t there. This is because for the last couple of weeks you&#39;ve been running against your local SQL 2008 (or SQL Express) database and you forgot that you did a few tweaks to make yourself an administrator. In the last couple of weeks you removed the code on the site that allows users to self-register since your application is an LOB app with a manually administered user list.</p><p>There is a built-in tool that comes with Visual Studio 2008 that allows you to do site administration. In a non-cloud environment, this was a great way to do things because you could simply configure your providers and then click &quot;Project&quot; and then &quot;ASP.NET Configuration&quot; and you would be taken to a Cassini-based website that allows you to add/remove users, manipulate roles, etc. It was great.</p><p>The problem is that when you run an Azure application locally, you&#39;re running the <em>Role</em>, you&#39;re not running the ASP.NET application. This means that when you launch (at least as of last night when I tried this) the ASP.NET configuration site, you&#39;re going to get a pile of errors all stemming from the fact that information contained in your service configuration file wasn&#39;t found and you&#39;ll get other errors because the <em>local fabric</em> doesn&#39;t get initialized when you don&#39;t start the app through the role.</p><p>So what can you do? If you can&#39;t use the admin site&nbsp; then how do you create an admin user that can then create more users? Lots of really talented people have contributed to the MVC community including a fully functional admin site that uses the membership provider to administer users, etc and you can use this if you want. What I&#39;ve been doing, however, to ensure that I&#39;m never left without <em>some</em> form of administrative access to my sites is by creating a <em><strong>root account</strong></em>.</p><p>What I do is in the service definition I declare three settings:&nbsp;RootAccountName, RootAccountPassword, AdminRoleName. I then have code in my application startup that will use the Membership API to create this user with the given password and add them to the Admin Role (and create that role if it isn&#39;t created already). This guarantees me that any time I do a fresh deploy or even wipe my storage account that I&#39;ll still be able to login as an administrator to stage or production and I can keep the root account name different between stage and production.</p><p>Again, Azure development is awesome and shares a lot of similarities with traditional ASP.NET development but some things (like the built-in site admin tool) don&#39;t work out of the box via the cloud and so we have to keep these things in mind as we build applications for the cloud.</p>]]></description><category>aspnet</category><category>mvc</category><category>azure</category><category>cloud</category><category>membership</category></item><item><title>Configuration Settings in Azure Applications</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/azure_configurationsettings.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/azure_configurationsettings.htm</link><pubDate>Mon, 28 Sep 2009 14:59:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=azure%5Fconfigurationsettings</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>One of the double-edged swords of Azure is that it feels so much like building regular web applications. This is a good thing in that you can re-use so much of your existing skills, knowledge, and best practices and they will still apply in the Azure world. However, it is really easy to make assumptions about how things work that turn out to be wrong.</p><p>For example, if you look at just about 99% of the Azure samples, blogs, and other reference material, you will see stuff that looks like the code below, sitting right inside <strong>web.config</strong>:</p><pre>&lt;add key=&quot;TableStorageEndpoint&quot; value=&quot;http://foo.table.core.cloudapp.net&quot;/&gt;<br />&lt;add key=&quot;QueueStorageEndpoint&quot; value=&quot;http://foo.queue.core.cloudapp.net&quot;/&gt;<br />&lt;add key=&quot;BlobStorageEndpoint&quot;&nbsp; value=&quot;http://foo.blog.core.cloudapp.net&quot;/&gt;<br />&lt;add key=&quot;AccountName&quot;&nbsp;&nbsp; value=&quot;foo&quot;/&gt;<br />&lt;add key=&quot;AccountSharedKey&quot;&nbsp;&nbsp; value=&quot;...lotsa stuff...&quot;/&gt;</pre><p>If you were to make assumptions about this, one might assume that you should be putting stuff like this in your web.config file even when you go to staging and production. NO! Stop right there!! This is not how Azure configuration settings are supposed to work!</p><p>Equally prevalent in the samples you will find calls to methods like <strong>GetDefaultTableStorageAccountFromConfiguration</strong>. there is actually a bit of useful logic going on in here that might not be immediately obvious.</p><p>This method is going to make attempts at getting configuration information from multiple different locations. It will check the web.config/app.config file, but it will also check your <em>service configuration</em> file. The most important thing to remember about this file is that it <em>can be edited directly from the Azure portal</em>. This means that you can deploy your application to stage and then go in and edit the service configuration file to change all the endpoints to your staging endpoints, then activate your app.</p><p>The reason this is important is because you never, <em>ever, ever</em> want to include your Azure key information in your web.config file, especially if you&#39;re posting on forums or sharing your code with other people. This is because if anybody gets your account name and shared key combination, they have full access to your Azure storage account and can basically run amok all over your data.</p><p>So, how do you know when you use a <em>service configuration</em> setting vs. a <em>web.config</em> setting? Here&#39;s a quick rundown:</p><ul><li>If you need to be able to edit the information after deploying, <em>it must be in service configuration</em> and <em><strong>not</strong></em> in web.config</li><li>If the information only changes once per full deploy to production, e.g. it&#39;s version bound not environment bound, you can leave the setting in web.config</li></ul><p>So, for example, in a typical Azure application, you might store the names of your queues and tables in web.config (because they should rarely change and will remain the same between stage and production), but you&#39;ll put the endpoint information related to your Azure Storage account in the service configuration file. </p><p>Hope this helps. The key thing to remember is that Azure service configuration can be a really powerful tool if you know its there... it can also screw you up if you forget its there :)</p>]]></description><category>azure</category><category>configuration</category><category>sdlc</category><category>cloud</category></item><item><title>The Rite of Spring</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/cassini_riteofspring.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/cassini_riteofspring.htm</link><pubDate>Thu, 24 Sep 2009 12:29:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=cassini%5Friteofspring</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Before I get to the blog post, <a href="http://ciclops.org///view_media/29012/The_Rite_of_Spring?js=1">go check out the image</a>. It&#39;s positively huge, so you might have to scroll a bit before you see something on a smaller monitor. </p><p>The main thing that I get from this picture is a feeling of awe. I mean, it&#39;s <em>Saturn</em> for crissakes... and we&#39;ve got a machine flying around that planet, taking pictures that can be assembled into the massive image in the link and <em>sending those pictures across the solar system back to machines on Earth</em>. Just take a deep breath and stop and think about that for a minute. Today we take virtually all things technological for granted - nobody notices that our phones are using more technology today than the super computers that launched man to the moon 40 years ago. Nobody seems to care that when we were younger, the most awesome kickass gaming rig was a 486 DX2 that ran at 66Mhz. 66<strong>Mhz</strong>! And that was really just a trick, it&#39;s clock speed was really only 33<strong>Mhz</strong>.</p><p>So now on any given day I can use the Internet, wirelessly, from a coffee shop, on a 13&quot; device that doesn&#39;t need to be plugged in all the time... and I can use that Internet to download an image of Saturn - taken by a spacecraft that man built and can be&nbsp;remotely controlled with <em>insane</em> resolution and detail (each of those little white-ish specks in the above image is actually a high-res moon, not a piece of dust on the camera lens...).</p><p>Maybe its just me, but the whole idea of this fills me with awe and wonder and I feel like a kid again when the universe was huge and the world was a playground full of stuff to learn and explore... and it leads me to just one question:</p><p>If we can put men on the moon and send scientific spacecraft to Saturn to take high-resolution photos, then <strong><em>why the $@#(!%)# can we not build a single piece of decent consumer-grade software that isn&#39;t slow and riddled with bugs</em></strong>?!</p><p>Enjoy the pic! :)</p>]]></description><category>saturn</category><category>nasa</category><category>science</category><category>cassini</category></item><item><title>ViewState is the Froo-It of the Dev-Il</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/viewstate_evil.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/viewstate_evil.htm</link><pubDate>Wed, 23 Sep 2009 15:09:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=viewstate%5Fevil</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>The other day I was running Microsoft&#39;s malicious software removal tool and, to my shock and horror, it did <em>not</em> remove all of my ASP.NET applications that make use of ViewState. I&#39;m sure it&#39;s just an oversight and Microsoft will be releasing a patch for that soon... if there is one application that could be called malicious, it&#39;s an app that uses ViewState.</p><p>Before I get into the rant proper, let&#39;s have a little history lesson. Back in the good old days when developers walked uphill both ways to their cubicle in the freezing snow and hail - there was &quot;classic&quot; ASP. This festering boil on the ass of developers everywhere allowed a big old pile of VBscript to be run inside a file that was also littered with markup. Eventually developers came up with some good practices (like doing everything in a <em>Sub Main</em>, etc) but the end result was still awful spaghetti and it was often very difficult to code multi-state pages because, well, you had to maintain all that state information yourself. Whether your page was in edit mode, confirmation mode, or edit + rainbow + candle mode - all stuff you had to code by hand.</p><p>So along comes ASP.NET. The people at Microsoft saw the developer difficulty in using ASP and thought, &quot;We should make the web development experience feel like the windows development experience, with double-click-to-create event handlers!&quot;</p><p>Nooooooooooooooooooooo! For the love of all that is good and geeky, Noooooooooooo! Web development <em><strong>should feel like web development dammit</strong>!! Web development can feel like web development and still be fun and elegant and easy!!</em></p><p>So.. to give developers the feeling that they&#39;re working in a windows world, even though they&#39;re on the web, the ASP.NET folks created ViewState. To imagine what this was like, picture one of those mad scientist laboratories where they&#39;re working on creating some kind of godzilla-mothra hybrid..they jam 1billion volts into it and it wakes up and spontaneously gives birth to a baby alien-monster... that&#39;s ViewState.</p><p>You can see a&nbsp;dramatic re-enactment of the birth of ViewState below. You can see the baby ViewState has escaped the host&#39;s stomach and is attempting to bring forth an era of dark evil the likes of which mankind has never before experienced....</p><div style="text-align: center"><img src="http://files.blog-city.com/files/J05/88284/p/f/alienviewstate.jpg" alt="" width="360" height="246" /></div><p>While their heart was in the right place, the implementation is just downright nasty. The web is not a windows development platform and the simple act of forcing developers to think about their web pages in terms of <em>events</em> and <em>postbacks</em> created a fundamental break between what&#39;s really happening on that page and what the developer&#39;s are dealing with. This eventually led to the abuse of ViewState, where <em>everything</em> shows up in that damn state bag. I&#39;ve looked at the inside of some pretty retchid ViewState and I&#39;ve been appalled by what I&#39;ve seen. I&#39;m <em>positive</em> that most developers have no clue what&#39;s inside the ViewState their page is generating. Many of them assume that because ViewState is a Microsoft invention, it&#39;s efficient and can&#39;t be abused. </p><p>I&#39;ve seen pages become anywhere from 300KB to 300<em><strong>MB </strong></em>(that&#39;s right, MB!) because of ViewState bloat. This creates a burden on both the server and the client: the client has to hold onto that bag and re-transmit it every time and the server has to de-serialize that insanity at the start of every request.</p><p>I&#39;m sure there will be people who comment on this blog that ViewState is good if used by properly disciplined people. Sure, that&#39;s true, I&#39;ve done it myself - if you spend a <em>ridiculous amount of time</em> optimizing the use of ViewState by your pages, you can trim it down so you&#39;re probably only adding 20-30KB of extra text to the rendered output. My advice, of course, is to simply not bother.</p><p>There are two avenues to take here:</p><ol><li><div>Use ASP.NET MVC instead. Finally you can go back to programming <em>like a web programmer</em> and ditch the stupid ViewState/Event/Postback goo.</div></li><li><div>Turn off ViewState. Turn it off system-wide and disable it on every page and user control. Then refactor your entire application to survive without it. Or, if this sounds like too much trouble, see #1 :)</div></li></ol><p>Yes folks, this is a rant so I&#39;ve deliberately exaggerated some of my opinions. For example, I do not believe that ViewState was birthed by an alien-monster hybrid in a lab. Come on, that&#39;s totally unrealistic. I do, however, believe that ViewState is the froo-it of the dev-il. That&#39;s for realz.</p><p>Also, bonus points if you can name the movie from which the &quot;froo-it of the dev-il&quot; reference originates :)</p>]]></description><category>viewstate</category><category>aspnet</category><category>evil</category></item><item><title>On Testing</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/ontesting.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/ontesting.htm</link><pubDate>Mon, 21 Sep 2009 17:53:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=ontesting</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>A while ago my mother found a bunch of my grade school (like 3rd - 5th grade era) report cards and progress reports. They pretty universally read like &quot;Kevin is struggling&quot; or &quot;Kevin is having a hard time&quot; and go on and on to describe that I&#39;m not doing well and that my mother really needs to fix it or else I&#39;m going to start failing, etc. I didn&#39;t feel stupid or incapable at the time, I just felt <em>entirely unremarkable</em>. I didn&#39;t feel as though there was a single thing about me that was any different than any other kid ... except maybe that I didn&#39;t do as well scholastically as my friends. Somehow, despite &quot;needing help&quot; and &quot;struggling&quot;, I was reading at a 12th grade level in 4th grade. I was placed in remedial to average classes until grade 8.</p><p>I didn&#39;t know it at the time, of course, but I had (and still have) ADD. I do not have any hyperactivity problems and in fact have sometimes been referred to as a sloth in the past. On subjects that I could obsess over and that interested me, I did exceptionally well (except for testing) and on boring subjects I did exceptionally bad (including testing).</p><p>A common thread here is testing. I have never tested well and never will. I hate the experience of being in a test. My stomach churns and I fidget, twitch, itch, and otherwise <em>cannot focus on the test</em>. I fail tests for easy and hard classes alike and only in recent adult years have I ever been able to pass a test on a boring topic (passed the MCSD exam for SQL Server 2005.. good <em>lord</em> that test was boring.. I had to take it twice to pass).</p><p>While in the middle of a test, there is a single thread running through my mind... it sounds like this &quot;I want to be done. I don&#39;t care if I get all the answers wrong I don&#39;t care if it ruins the rest of my life I don&#39;t care I don&#39;t care <strong><em>I want to be done!!!</em></strong>&quot;. I remember a mid-term exam for Calculus once while at University - I was maintaining a decent Bish/Cish average. I got to the mid-term, <em>panicked</em>, and randomly picked all answers on the test and fled the mid-term 15 minutes after the exam began. I failed it and tanked my average. </p><p>When someone with my particular type of ADD is confronted with a long-running task that gives them anxiety such as studying for an exam, I have two standard responses: </p><ol><li>Obsess about the studying for, preparation for, and acing of, said exam <em>to the exclusion of all else, including daily responsibilities such as acknowledging the presence of one&#39;s family and friends</em>.</li><li>Ignore it. Avoid it. Run like hell and pretend the exam doesn&#39;t exist. When it comes time to take the test, pick random answers and be done with it as soon as humanly possible.</li></ol><p>Unfortunately, I have in the past done both #1 <strong><em>and</em></strong> #2. I&#39;ve spent <em>months</em> preparing for an exam and then blew it off out of raw, primal <em>fear</em> when it came time to take the test. That allows me to wallow in self-pity for months after receiving my 0% grade, further increasing my test-related anxiety.</p><p>Want to hear how the cycle of self-destruction continued? I decided to start learning Japanese a while back. I felt as though the study of it was floundering (though I was having a <em>crapload of fun) </em>so I decided maybe if I set a goal, some kind of target, then I&#39;d have more productive studies. What did I set as my goal? Why, the <em>JLPT3 Japanese Language Proficiency Test</em>, a once-a-<em>year</em>, international certification. So I did my usual - I turned what was once a fun passtime/hobby into a hyper-obsessed anxiety-ridden downward spiral while preparing for this test.</p><p>So I&#39;ve decided to not take the test.. <em>ever</em>. Regardless of whether or not I think I can pass it, I&#39;ve decided not to take it. Within minutes of making this decision, I felt happier, lighter, and less stressed. The ominous, looming shadow of the upcoming test went away and learning Japanese became instantly fun again.</p><p>So what&#39;s the moral of the story? I&#39;m not really sure. A wise friend of mine once passed a quote (perhaps paraphrased) on to me that everyone should live by:</p><p><em><strong>&quot;Find out what you don&#39;t like doing, and stop doing it.&quot;</strong></em></p><p>Simple, yet powerful.</p>]]></description><category>testing</category><category>personal</category><category>editorial</category></item><item><title>Does Google Translate Suck Just as Bad as all the other Machine Translators?</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/googletranslate_nobetter.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/googletranslate_nobetter.htm</link><pubDate>Thu, 17 Sep 2009 12:33:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=googletranslate%5Fnobetter</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Before I get into the main part of the blog post, I want to preface this whole thing by saying that I am well aware of the problems of doing language translation by a machine. It&#39;s an inherently difficult problem. </p><p>My issue here isn&#39;t so much with Google Translate as it is with the public perception of Google. I&#39;ve read a few reviews of Google Translate and seen some blog posts. The general consensus is that because Google built it, its awesome and flawless. People think that Google is building this massive, soon-to-become-self-aware giant brain in the cloud that is sucking intelligence out of search patterns to be used for some world dominating purpose in the future. This is rubbish because we know Google doesn&#39;t start Judgement Day, Cyberdyne does. Sheesh, anybody knows that.</p><p>So, what&#39;s different about Google Translate than other previous attempts at machine translation? The biggest is that Google is using collective intelligence like it uses on its search engine to cull human-supplied translation bits and add those to its existing translation rules. The theory is that it makes for a better engine and should make the translations more in line with what a human would expect.</p><p>So how does it fare? You tell me:</p><p><table border="0" style="width: 826px; height: 48px"><tbody><tr><td><strong>My Input&nbsp;</strong></td><td><strong>Google&#39;s Output&nbsp;</strong></td><td><strong>&nbsp;Actual Meaning</strong></td></tr><tr><td>&nbsp;内閣は倒れるだろうということだ</td><td>Cabinet and they will fall</td><td>They say that the cabinet (govt) will fall</td></tr><tr><td>&nbsp;その先生は病人だということが分かった</td><td>The teacher found that it&#39;s sick</td><td>The teacher turned out to be sick</td></tr><tr><td>&nbsp;私達は彼の死を悲しんだ</td><td>We mourned the death of his</td><td>We mourned his death</td></tr><tr><td>&nbsp;彼の殺人の動機は何だ</td><td><div id="result_box" dir="ltr">What&#39;s his motive for murder</div></td><td><div id="result_box" dir="ltr">What&#39;s his motive for murder?</div></td></tr></tbody></table></p><p>So this is actually pretty enlightening. I have to admit that I was really skeptical when I tried it out. Just like <em>every other machine sentence translator</em> on the planet, if you attempt to use a Google translation to glean meaning from a web page or from a paragraph or even a single sentence, you&#39;re probably screwed. The first three sentences I have in the chart show that while verbs and nouns are translated properly, you actually lose a lot of meaning and context in translation. For example, the second sentence - relying on the Google translation I don&#39;t know if the teacher is sick or something else - but it&#39;s pretty damn close to accurate. The second to last sentence is almost spot on and finally, the last sentence is a <em>perfect</em> translation.</p><p>So the verdict is this: the current state of machine language translation sucks and will continue to suck for some time. However, I now know that if I want to get a rough stab at a translation of something I am going to try Google Translate first. Among all the other engines I could find, Google&#39;s was far and away the best.</p><p>For example, when I plug in the Japanese for &quot;what&#39;s his motive for murder?&quot; Babelfish spits out the following: <em><strong>Motive of at that homicide is what</strong></em>.</p><p>Someday this won&#39;t matter and we&#39;ll all have universal translators in our ears. It also doesn&#39;t matter much because, as Hollywood has shown us time and time again, all aliens from far and distant worlds speak English.</p>]]></description><category>google</category><category>translation</category><category>language</category><category>japanese</category></item><item><title>What's the Difference Between Web Hosting and Cloud Computing?</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/cloud_vs_webhosting.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/cloud_vs_webhosting.htm</link><pubDate>Fri, 04 Sep 2009 12:12:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=cloud%5Fvs%5Fwebhosting</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Yesterday a friend of mine was asking me what I&#39;ve been doing lately in my spare time. When I mentioned that I&#39;d been doing a lot of messing around with Windows Azure, he was naturally curious. After explaining what Azure is, he asked me what the difference was between Windows Azure, a cloud computing environment, and traditional web hosting scenarios.</p><p>On a really high level, he&#39;s got a valid point : With Azure you can develop your application offline locally and then when you&#39;re done you can publish it to a remote host. To the casual observer, this looks exactly like what you might do with a web hosting company that provides space on an IIS box and let&#39;s you use ASP.NET and maybe even a little SQL server database. </p><p>The beauty, of course, is that to the end user it doesn&#39;t matter. To someone using your website, they don&#39;t (and shouldn&#39;t) care whether your website is being hosted in Windows Azure or a traditional web hosting server environment. The real difference is the underlying plumbing.</p><p>In a traditional web hosting environment, the company to whom you&#39;re paying your monthly fees has a bunch of Windows Server boxes (virtual or otherwise). Each of these has IIS on it and the .NET Framework. When you rent a website space from them, they create a virtual directory/IIS application (possibly even an App pool if they&#39;re nice) for you. So, on their system your application might be at server203/customer909312093 and they very nicely provide a DNS mapping so that www.yourapp.com points to that location on their system and the end users never know about how this plumbing works. The key architectural points to consider here at that there is a single point where your application resides - 1 IIS server, 1 app pool, 1 application/virtual directory within that pool. There is a single SQL server instance, also hosted in a single physical location, and a single database within that SQL server instance that contains your stuff. It is a classic example of the client/server model, with the server parts being hosted by the web host company and the client parts being browsers and other web consumers. </p><p>Cloud computing is different. By its very nature it is distributed. When you develop a web application in Windows Azure, there is a chance that there might be 10 different instances of your application running in 10 different data centers throughout the world. This application could be pulling data from partitioned storage in 5 different data centers throughout the world. There can be 5 different instances of the &quot;engine&quot; (a worker role; C# class) running in 5 different data centers, all working on processing the information that your application is taking in and spitting out. Writing a scalable, robust, reliable application in Azure involves being mindful of the architecture of &quot;the cloud&quot;, but you don&#39;t need to worry about things like how to implement hot failover. You don&#39;t have to worry about things like what happens when your web-hosted site gets crushed under the &quot;Digg&quot; effect or &quot;Slashdotted&quot; - if that happens on Azure you just go to the admin site and bump up the number of running instances of your web role and maybe your worker role (you can scale them differently).</p><p>Azure is a game-changer. It completely changes the way people think about building scalable and reliable web applications available on the Internet. In addition, other Azure services like the .NET Service Bus allow websites sitting &quot;in the cloud&quot; to securely and reliably communicate with servers sitting inside your corporate infrastructure without opening firewall ports or causing security problems. This allows scenarios like you being able to build an e-Commerce website that sits in the cloud and it can communicate new orders directly to your internal fullfillment system without requiring you to create a gap in your security. The list of scenarios is endless.</p><p>The bottom line here when thinking about web hosting vs. Azure is this: Do you want to put up some HTML that might have a limited amount of interactivity or are you trying to publish an actual <span style="font-style: italic">application</span>? If you want to build an application in the cloud then Azure is your tool... it&#39;s not a tool, it truly is an Operating System - an Operating System and SDK for building cloud applications.</p><p>Obviously I will be posting more details about Azure, cloud computing, and code samples :) Some of what I&#39;ve got planned is still under wraps and I can&#39;t spill the beans just yet. </p>]]></description><category>cloud</category><category>azure</category><category>webhosting</category><category>architecture</category></item><item><title>Live Framework Developers (particularly MEWA devs) get boned. Film at 11.</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/live_framework_offline.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/live_framework_offline.htm</link><pubDate>Wed, 02 Sep 2009 17:46:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=live%5Fframework%5Foffline</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>I was just flipping through my daily RSS feeds when I stumbled on a gem from the Live team, which you can read <a href="http://dev.live.com/blogs/devlive/archive/2009/08/21/500.aspx"><em><strong>here</strong></em></a> . This is a fairly confusing post, but this is basically what I&#39;ve been able to interpret from it:</p><ul><li>What we know as the Live Framework, that many of us have been developing with for nearly a year (bits released PDC 2008) will be disabled/deactivated/removed as of September 8th, 2009 (6 days from today)</li><li>The end user experience for Live Mesh will remain untouched. In other words, people who have been using Live Mesh as a distributed file share system will be able to continue doing so. Pavan and I wrote a book sharing our chapters using Live Mesh so this is a good thing.</li><li><em>The ability for developers to create Silverlight Mesh-Enabled Web Applications will be disabled</em>.&nbsp;</li><li>If you have any data in a developer Live Framework mesh, you&#39;d better get it out of there now because it will be removed.</li><li>You should remove all your devices from developer meshes.</li></ul><p>When I first read this, I was all &quot;OMFGWTFNoMesh!?!&quot; and exploded in front of my computer. After cleaning the bits of my exploded brain off the keyboard and looking at it again, some of it made sense. They are taking the Live Framework stuff down and theoretically coming up with a better, more in-depth, more unified API for Live. This step is long overdue because for a very, very long time developers have been confused because there is &quot;old live framework&quot; and then &quot;live mesh/live framework&quot; and then there&#39;s Azure and then there&#39;s a bunch of crap that&#39;s been labelled as part of &quot;Live&quot; for which there is no developer API.</p><p>What I expect to happen is that when they come back after hiatus, the Live developer experience will be a far more unified, robust, and more importantly, clear-and-concise experience. Unfortunately, all of us who have spent a truckload of time building MEWA prototypes are boned.</p><p>That said, if we eventually regain the ability to access/create/manipulate meshes from inside a Silverlight application, we can easily host a mesh-enabled web application in Azure. This doesn&#39;t change the fact that I&#39;m pissed about the fact that MEWAs have suddenly become a dead-end for development and I have no idea if I will ever be able to develop an application that synchronizes across all Live Framework devices written in Silverlight again.</p><p>BOO. </p>]]></description><category>silverlight</category><category>mewa</category><category>mesh</category><category>liveframework</category></item><item><title>How Win7's "Boot to VHD" Feature has Changed the Way I Work</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/win7_vhd.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/win7_vhd.htm</link><pubDate>Fri, 28 Aug 2009 15:10:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=win7%5Fvhd</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>Recently I was reading the <strong>Hanselblog</strong> when I discovered these two articles <a href="http://www.hanselman.com/blog/LessVirtualMoreMachineWindows7AndTheMagicOfBootToVHD.aspx">here</a> and <a href="http://www.hanselman.com/blog/LessVirtualMoreMachineWindows7AndTheMagicOfBootToVHD.aspx">here</a>. Before I get to what I&#39;ve been doing, I want to recap my usual machine (virtual and physical) usage scenarios:</p><ul><li>A clean host, this is what I do my day-to-day stuff on : writing, browsing, e-mail, gaming</li><li>virtual machines all over the damn place: every beta, CTP, limited new ultra-shiny thing gets put in a VM and played with until my eyes bleed.</li></ul><p>This is normally an adequate situation for me. However, with some things I just don&#39;t want the virtualization overhead or the difference in environment. For example, VS2010&#39;s GUI is written in WPF and that particular GUI <em>hates</em> being virtualized. When put under a virtual machine running Windows 7, VS2010 fails to render things, borders disappear, windows become unusable and the experience is downright awful. On the other hand, when you run VS2010 &quot;bare metal&quot; with no virtualization between it and your video card, everything is beautiful and all works well. </p><p>When reading the blog posts about the VHD boot feature, I realized that I could have my cake and eat it too. I could have the sandboxing, isolation, and easy throw-away that I typically require for evaluating betas and CTPS...but I could also run the sandbox un-virtualized and only incur a 3-4% performance penalty on disk I/O by running inside a single file rather than running in a directory or partition. I can handle that.</p><p>So now I&#39;ve got a VHD on my laptop that boots into Windows 7 Ultimate with a full install of VS2010 and SQL Server 2008 that I can use as a sandbox for building next-gen applications. I&#39;ve also got a Win2k8 R2 sandbox that is waiting for Biztalk 2009 and/or whatever other server product I want to evaluate. And if I want I can have another sandbox for Win7 that has other CTPs and betas that don&#39;t exactly play nice with the current revision of Visual Studio 2010. The only real penalty I have is waiting for a reboot...which is fast on my laptop and painfully slow on my tower.</p><p>So.. if you like the isolation, sandboxing, safety, and easy throw-away features you get from virtualization but you don&#39;t need to actually have multiple sandboxes running at any given time, then I think using the Boot to VHD option is quite possibly the best developer feature I&#39;ve ever seen in an Operating System to date.</p><p>Anyway, I&#39;ve got more good stuff to come, I&#39;ve been spending a crazy amount of time writing Azure apps on ASP.NET MVC and I&#39;m about to start dumping all kinds of goodness on the blog (assuming anybody actually reads this thing anymore).</p><p>So go forth, make your VHD files, share them among your friends and co-workers, and enjoy the awesomeness that is Windows 7.</p>]]></description><category>win7</category><category>vhd</category><category>virtualization</category></item><item><title>Silverlight Polling Duplex Channel is NOT a Scalable Solution</title><guid isPermaLink="true">http://dotnetaddict.dotnetdevelopersjournal.com/sl_polling_duplex.htm</guid><link>http://dotnetaddict.dotnetdevelopersjournal.com/sl_polling_duplex.htm</link><pubDate>Wed, 01 Jul 2009 12:41:00 GMT</pubDate><comments>http://dotnetaddict.dotnetdevelopersjournal.com/console/comments/popup/?f=sl%5Fpolling%5Fduplex</comments><dc:creator>Kevin Hoffman</dc:creator><description><![CDATA[<p>First, let&#39;s talk about the problem that Polling Duplex solves. Polling Duplex is a special WCF channel that is <em>available only to Silverlight</em>. When your Silverlight application needs data from the server, it needs it in one of two different ways: </p><ul><li>On-Demand : Something in your application happens and it needs data. It specifically asks the server for that data upon encountering the need for that data. This is what most people think of as &quot;pull&quot; data. </li><li>Push : This is where you need data sent to your application as the data becomes available and the overhead of setting up a timer on which you pull (or poll) for data is unacceptable to you. The main reason why this is unacceptable to people is because there may be frequent periods of time where the pull/poll has no data, which means your app will be occupying server resources every X seconds even when there is nothing to do.</li></ul><p>The Polling Duplex channel is a solution to the push problem. It allows server-side code to &quot;push&quot; data down to the Silverlight application. Under the hood the channel is using &quot;Comet&quot;-style tricks keeping HTTP connections open in much the same way that the Gmail application is able to receive push notifications of new mail.</p><p>This is great and the programming model for communicating with the Polling Duplex channel is brain-dead simple. It does <em>NOT get any easier </em>to implement push data to a RIA - not in Flash, not in AIR, and certainly not in JavaFX. The problem is that this solution doesn&#39;t scale. On the server side, for each concurrently running Silverlight application (so probably one per concurrent user), there is a full live socket being consumed that will not be relinquished until the client disconnects/closes their browser.</p><p>Worse is that the Polling Duplex channel defaults to only allowing 10 concurrent connections. You can programmatically tweak that by configuring the throttling behavior (as shown in this <a href="http://weblogs.asp.net/alexeyzakharov/archive/2009/04/17/how-to-increase-amount-of-silverlight-duplex-clients.aspx" target="_blank">blog post here</a> ).Even if you do increase the amount of concurrent connections allowed, those concurrent connections are still going to beat the crap out of your servers and good luck getting that to work seamlessly in a cluster/farm scenario. </p><p>If you need more than a handful of concurrent users and you want to do it in a way that scales and doesn&#39;t abuse your servers, then I highly, highly recommend looking into some kind of messaging / open gateway server. The only one I&#39;ve played with for more than a few minutes is <a href="http://www.kaazing.org/confluence/display/KAAZING/Home" target="_blank">Kaazing</a> , but I have nothing but good things to say about it. It&#39;s based on HTML 5 Web Sockets so you will be in good shape for the future. </p><p>Web Sockets are freaking awesome but that&#39;s a topic for another post.</p><p>Bottom line here is that if you&#39;re looking at any of the Polling Duplex samples online like the &quot;stock ticker&quot; sample, don&#39;t be fooled. It looks easy, but especially in the financial industry, you need high concurrency, high speed, low latency - and you&#39;re not going to get that with the polling duplex channel. If there was one place where I see it fitting is in the creation of intranet applications internal to an organization with a limited number of concurrent users. </p>]]></description><category>silverlight</category><category>duplex</category><category>wcf</category><category>polling</category><category>push</category></item></channel></rss>
