<?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.jeffhandley.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:image="http://purl.org/rss/1.0/modules/image/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>Jeff Handley</title>
        <link>http://jeffhandley.com/Default.aspx</link>
        <description />
        <language>en-US</language>
        <copyright>Jeff Handley</copyright>
        <generator>Subtext Version 2.5.0.3</generator>
        <creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license>
        <image>
            <title>Jeff Handley</title>
            <url>http://jeffhandley.com/images/RSS2Image.gif</url>
            <link>http://jeffhandley.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.jeffhandley.com/JeffHandley" /><feedburner:info uri="jeffhandley" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
            <title>Stop SOPA and PIPA</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/Xd2UMJ87A7s/Stop-SOPA-and-PIPA.aspx</link>
            <description>&lt;h1&gt;Please do not allow SOPA, PIPA, or any forms of Internet censorship or regulation to get through Congress.&lt;/h1&gt;  &lt;h2&gt;Over the past several years I've noticed a trend in our government where we've shifted away from laws protecting citizens from corporations and government to laws protecting corporations and government from citizens. This is coming at the cost of our liberty and pursuit of happiness.&lt;/h2&gt;  &lt;h2&gt;By preventing SOPA, PIPA, or other Internet censorship/regulation, you can help reverse this trend.&lt;/h2&gt;  &lt;h3&gt;Thank you,   &lt;br /&gt;Jeff Handley&lt;/h3&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;I am submitting this text to my senate and house representatives, and I’m also making all pages on this blog redirect &lt;a href="http://sopa.jeffhandley.com" target="_blank"&gt;a PSA page&lt;/a&gt; until 1/19/2012 as part of my effort to stop SOPA and PIPA.&lt;/p&gt;&lt;img src="http://jeffhandley.com/aggbug/284.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/Xd2UMJ87A7s" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2012/01/17/Stop-SOPA-and-PIPA.aspx</guid>
            <pubDate>Wed, 18 Jan 2012 06:10:25 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2012/01/17/Stop-SOPA-and-PIPA.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/284.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2012/01/17/Stop-SOPA-and-PIPA.aspx</feedburner:origLink></item>
        <item>
            <title>Merry Christmas! It&amp;rsquo;s my off-site backup.</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/wz1cRDgDkxc/Merry-Christmas-Itrsquos-my-off-site-backup.aspx</link>
            <description>&lt;p&gt;Almost 4 years ago, &lt;a href="http://jeffhandley.com/archive/2008/04/06/leaving-big-and-relocating.aspx" target="_blank"&gt;I moved my family&lt;/a&gt; from Cincinnati, Ohio to Redmond, Washington so that I could join Microsoft.  Since we have two young children, and a small family, the move has been really hard on the grandparents.  But as our first Christmas out here approached, I came up with an idea that I’ve been repeating each year since.  Last night, I tweeted about this idea and the tweet went a bit viral, with hundreds of retweets (thanks largely to &lt;a href="https://twitter.com/#!/shanselman/status/148342981102018560" target="_blank"&gt;Scott Hanselman&lt;/a&gt;, I’m sure).&lt;/p&gt;  &lt;blockquote class="twitter-tweet"&gt;   &lt;p&gt;Every year I give the grandparents DVDs with all of our digital pictures from the year. To them it's a gift. To me it's off-site backup.&lt;/p&gt; — Jeff Handley (@JeffHandley) &lt;a href="https://twitter.com/JeffHandley/status/148341892940181504" data-datetime="2011-12-18T10:00:37+00:00"&gt;December 18, 2011&lt;/a&gt;&lt;/blockquote&gt; &lt;script src="//platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;  &lt;p&gt;Like many families, we take thousands of digital photos and we store them on an HP MediaSmart HomeServer.  Every year for the last 4 years, I sit down the weekend before Christmas, copy all of the year’s pictures from the HomeServer to my PC, organize them into folders of 4GB, burn them to DVD, and then send them to the grandparents as my Christmas gift to them.  What they don’t know (until now anyway), is that the gesture isn’t completely selfless.  As succinctly expressed in my tweet, those disks are my off-site backup of our family photos.  And we’re talking 2300 miles off-site, so I consider myself pretty well covered.&lt;/p&gt;  &lt;p&gt;Here are a few details for my process, in case you decide to pick up this routine too:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Organize the photos into folders with the year, subfolders with the year-month, then subfolders again with year-month-day, and file names that have date-time stamps.  (I store these on our HomeServer). &lt;/li&gt;    &lt;li&gt;When copying the folders in preparation for the year’s disks, always include December from the previous year, so that photos from the previous Christmas are included in the set. &lt;/li&gt;    &lt;li&gt;Split the photos into groups of ~4GB, and burn the groups to disks.  This year I had 7 DVDs. &lt;/li&gt;    &lt;li&gt;Deliver the disks to the grandparents, and ideally copy the photos to their PC and add them to the screensaver. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;My wife and I have agreed many times that in the case of a disaster, our family photos are what we’d miss the most.  Having all of our photos archived at the grandparents’ offers us a bit of reassurance that we’ll never lose them.  And you cannot imagine how much joy the grandparents get when they watch the photo slideshow.  We’ve spent several hours sitting together watching the screensaver.&lt;/p&gt;  &lt;p&gt;In the days of Angry Birds, this is what I call killing two stones with one bird.  Merry Christmas!&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:749a6e33-37ae-4176-9e8c-0fa5af56cc93" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/HomeServer" rel="tag"&gt;HomeServer&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Family+Photos" rel="tag"&gt;Family Photos&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Backup" rel="tag"&gt;Backup&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/283.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/wz1cRDgDkxc" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/12/19/Merry-Christmas-Itrsquos-my-off-site-backup.aspx</guid>
            <pubDate>Mon, 19 Dec 2011 08:26:29 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/12/19/Merry-Christmas-Itrsquos-my-off-site-backup.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/283.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/12/19/Merry-Christmas-Itrsquos-my-off-site-backup.aspx</feedburner:origLink></item>
        <item>
            <title>WCF RIA Services V1.0 SP2 Released</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/AqUInbQqOho/WCF-RIA-Services-V1-0-SP2-Released.aspx</link>
            <description>&lt;p&gt;On December 9, 2011, Silverlight 5 was released.  As always, RIA Services is included in the &lt;a href="http://go.microsoft.com/fwlink/?LinkId=229318" target="_blank"&gt;Tools for Silverlight&lt;/a&gt;, and this new release included our V1.0 SP2 final build.  We refer to this as our RTW build, meaning Released-To-Web.  In addition to the Tools installer including WCF RIA Services V1.0 SP2, you can also find the standalone installer on &lt;a href="http://go.microsoft.com/fwlink/?LinkID=227926" target="_blank"&gt;Microsoft Download Center&lt;/a&gt;.  The &lt;a href="http://silverlight.net/getstarted/riaservices" target="_blank"&gt;silverlight.net/getstarted/riaservices&lt;/a&gt; page was also updated to reflect the new release.&lt;/p&gt;  &lt;p&gt;Aside from some bug fixes here and there, not much changed between SP2 RC and SP2 RTW.  The primary focus as been ensuring really solid compatibility with both Silverlight 5 and Silverlight 4 with this release, and testing the bits on tons of configurations for both design-time and runtime.  If you are upgrading from V1.0 SP1 to V1.0 SP2 though, here’s what you’ll find in this release:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Support for both Silverlight 4 and Silverlight 5 (SP1 had subtle issues that would cause bugs in SL5 apps)&lt;/li&gt;    &lt;li&gt;DateTimeOffset support&lt;/li&gt;    &lt;li&gt;Entity Framework Code-First development, using &lt;a href="http://nuget.org/packages/RIAServices.EntityFramework"&gt;this NuGet package&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;There are some more details in my &lt;a href="http://jeffhandley.com/archive/2011/09/02/RIAServicesSP2RC.aspx" target="_blank"&gt;SP2 RC announcement&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Known issues include:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Entity Framework 4.1 is required, but version 4.2 isn’t supported yet&lt;/li&gt;    &lt;li&gt;Requires Visual Studio 2010 or SP1. Visual Studio 11 isn’t supported yet&lt;/li&gt;    &lt;li&gt;Work on supporting Universal Providers for improved Windows Azure deployment is ongoing&lt;/li&gt;    &lt;li&gt;If you want to create a Silverlight 4 Business Application Template, first create an instance of the Silverlight 5 template, and then use the Silverlight project properties to retarget it to Silverlight 4. You might see some temporary errors (System.Windows.Markup.XamlParseException) in the designer and error window, but rebuilding will make those disappear.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I want to send a shout out to &lt;a href="http://hashtagfail.com/post/13978432034/ria-services-sp2" target="_blank"&gt;Yavor Georgiev&lt;/a&gt; and point you to his blog, as he has been driving this SP2 RTW release for the last couple of months.  I’ve transitioned off of the WCF RIA Services team and over to ASP.NET Web Pages, NuGet, and Razor.&lt;/p&gt;  &lt;p&gt;If you have any questions or issues with the SP2 release, jump over to the &lt;a href="http://forums.silverlight.net/53.aspx" target="_blank"&gt;forums&lt;/a&gt;.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:6966778c-ad83-455e-9201-98b893671d55" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/RIAServices" rel="tag"&gt;RIAServices&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/282.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/AqUInbQqOho" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/12/12/WCF-RIA-Services-V1-0-SP2-Released.aspx</guid>
            <pubDate>Tue, 13 Dec 2011 07:04:51 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/12/12/WCF-RIA-Services-V1-0-SP2-Released.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/282.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/12/12/WCF-RIA-Services-V1-0-SP2-Released.aspx</feedburner:origLink></item>
        <item>
            <title>GitHub, Triggered Deployments, and In-Browser Editing</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/HB_IY_Kkidc/To-The-Cloud.aspx</link>
            <description>&lt;p&gt;Earlier this month, I explored using &lt;a href="http://jeffhandley.com/archive/2011/10/08/WebMatrix-Git-AppHarbor.aspx" target="_blank"&gt;WebMatrix, Git, and AppHarbor&lt;/a&gt; to quickly create and publish a web site in the cloud.  While at work this afternoon I got a phone call from a relative with a usability issue on the site.  To fix the issue, I simply needed to wrap a hyperlink around an image, but I only had about 60 seconds to spare, which wasn’t enough time.  Here’s what I would have needed to do:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Open up a command prompt and cd into D:\github &lt;/li&gt;    &lt;li&gt;git clone https://jeffhandley@appharbor.com/xanderhandley.git &lt;/li&gt;    &lt;li&gt;Open the offending cshtml file, make the edit &lt;/li&gt;    &lt;li&gt;git commit –am "Made the popcorn site image a hyperlink" &lt;/li&gt;    &lt;li&gt;git push https://jeffhandley@appharbor.com/xanderhandley.git &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Okay, so in retrospect it would have only taken about 120 seconds to do, but at that moment, I didn’t think I could do it in the minute I had to spare.  I am going to use this opportunity to introduce GitHub into my workflow and be prepared for these kinds of adjustments should they arise again.&lt;/p&gt;  &lt;h3&gt;GitHub&lt;/h3&gt;  &lt;p&gt;I will describe GitHub by quoting their own site:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;GitHub is the best way to collaborate with others. Fork, send pull requests and manage all your &lt;strong&gt;public&lt;/strong&gt; and &lt;strong&gt;private&lt;/strong&gt; git repositories.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s also a nice and free place to clone my repositories in the cloud so that I don’t have to worry about backups and whatnot.  And honestly, it’s kind of a “central” repository for distributed version control. Don’t hate–you know you think of it that way too.&lt;/p&gt;  &lt;p&gt;When I first created and published my son’s popcorn site though, GitHub wasn’t needed in the workflow.  Instead, I just went directly from my PC to the cloud.  But with today’s episode, I needed to be able to get the latest version of the code on my work computer.  I wanted a central repository, and starting tonight, GitHub will serve that purpose.  Here’s how:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Go to &lt;a href="http://github.com"&gt;http://github.com&lt;/a&gt; and sign up / log in &lt;/li&gt;    &lt;li&gt;Create a New Repository &lt;/li&gt;    &lt;li&gt;On my home PC, where my existing repository is for the project, open a command window &lt;/li&gt;    &lt;li&gt;git remote add origin https://jeffhandley@github.com/jeffhandley/XanderHandley.git &lt;/li&gt;    &lt;li&gt;git push –u origin master &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I now have my &lt;a href="https://github.com/jeffhandley/XanderHandley" target="_blank"&gt;repository cloned up in GitHub&lt;/a&gt; and I can push changes to it.  But just like with regular expressions, now I have two problems.  When I want to deploy an update to the website, I need to get the updates to both GitHub and AppHarbor.&lt;/p&gt;  &lt;h3&gt;Triggered Deployments&lt;/h3&gt;  &lt;p&gt;Fortunately, GitHub has a feature that turns the two problems (of pushing to both GitHub and AppHarbor) back into 1 problem.  I can configure a Service Hook in GitHub such that any time I push an update to GitHub, the changes are also automatically pushed to AppHarbor.&lt;/p&gt;  &lt;p&gt;Here’s how to do it:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;On GitHub, while viewing the files for your repository, click on the “Admin” button at the top &lt;/li&gt;    &lt;li&gt;Click on “Service Hooks” on the left &lt;/li&gt;    &lt;li&gt;Select AppHarbor &lt;/li&gt;    &lt;li&gt;Open a new tab in your browser and go load up your AppHarbor application &lt;/li&gt;    &lt;li&gt;Under where AppHarbor shows your Repository URL, you’ll see a link next to “Create build URL” – click that to see your build URL &lt;/li&gt;    &lt;li&gt;Paste the Application Slug and Token into the AppHarbor Service Hooks configuration in GitHub as they explain, make the hook Active, and click Update Settings &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The GitHub repository is now set up so that any push into my master branch on GitHub will also push to AppHarbor.  To verify this, I just went through the following steps:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Opened the website on my home PC &lt;/li&gt;    &lt;li&gt;Made the change, adding the hyperlink &lt;/li&gt;    &lt;li&gt;Opened a command prompt where the website files are &lt;/li&gt;    &lt;li&gt;git commit –am "Made the popcorn site image a hyperlink" &lt;/li&gt;    &lt;li&gt;git push origin master &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I then refreshed github and saw the commit listed there.  Then I went over to AppHarbor and refreshed and saw the commit there too.  Then I went to &lt;a href="http://xanderhandley.com/popcorn"&gt;http://xanderhandley.com/popcorn&lt;/a&gt; and refreshed and saw the new hyperlink.&lt;/p&gt;  &lt;h3&gt;In-Browser Editing&lt;/h3&gt;  &lt;p&gt;With all of this magic awesomeness, I was thinking it couldn’t be any easier to edit Xander’s website.  But sure it can.  Now that I have GitHub and AppHarbor connected, I can utilize another goodie that GitHub has to offer: in-browser editing.  GitHub allows you to edit files directly in the browser; just browse to a file and click on the “Edit this file” button.  You’ll get a text editor in the browser, along with a commit message box and a “Commit Changes” button.  That’s right, you can make single-file edits directly in the browser and commit them to your repository in GitHub.  After committing, the service hook we configured will be executed, and the change will be deployed to AppHarbor immediately.&lt;/p&gt;  &lt;p&gt;I just exercised this capability by editing default.cshtml, adding a “This page intentionally left blank” message to it, and committing the change.  Within seconds, that change was deployed to xanderhandley.com.  I now have an in-browser editor of my son’s website such that any changes I commit are immediately deployed to the cloud.  This certainly isn’t a routine I’d use for a business website or anything remotely complicated, but for my son’s website, this is perfect.  And it’s free.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:56d316fe-f345-4af7-8775-dfa5caea0bfe" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Git" rel="tag"&gt;Git&lt;/a&gt;,&lt;a href="http://technorati.com/tags/AppHarbor" rel="tag"&gt;AppHarbor&lt;/a&gt;,&lt;a href="http://technorati.com/tags/GitHub" rel="tag"&gt;GitHub&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/281.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/HB_IY_Kkidc" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/10/25/To-The-Cloud.aspx</guid>
            <pubDate>Tue, 25 Oct 2011 07:01:40 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/10/25/To-The-Cloud.aspx#feedback</comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/281.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/10/25/To-The-Cloud.aspx</feedburner:origLink></item>
        <item>
            <title>WebMatrix, Git, and AppHarbor</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/OcYmvXXTKAk/WebMatrix-Git-AppHarbor.aspx</link>
            <description>&lt;p&gt;I needed to crank out a single-page web site for my son, to help him promote his popcorn sales for cub scouts.  I decided it was a perfect opportunity to try some new things, so I jumped into WebMatrix to create the site, added it to a Git repository, and deployed it to AppHarbor under Xander’s own domain name.  Start to finish, it took 30 minutes and my son gave me an A+.&lt;/p&gt;  &lt;h3&gt;&lt;a title="Install WebMatrix 2 Beta Now" href="http://www.microsoft.com/web/handlers/webpi.ashx?command=getprereleaseinstaller&amp;amp;appid=webmatrix" target="_blank"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Install WebMatrix 2 Beta Now" border="0" alt="Install WebMatrix 2 Beta Now" align="right" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/ASP.NET-Web-Pages-WebMatrix-Git-and-AppH_12A63/image_e61c6c3d-c7e6-4703-9fa0-3991a847a6f7.png" width="488" height="109" /&gt;&lt;/a&gt;Installing WebMatrix&lt;/h3&gt;  &lt;p&gt;WebMatrix is one of the easiest-to-install Microsoft products ever.  Really.  Just go to &lt;a href="http://www.microsoft.com/web/webmatrix/"&gt;http://www.microsoft.com/web/webmatrix/&lt;/a&gt; and click the big green button for “Install WebMatrix” or “Or try the latest Beta.”  I decided to try the latest beta, and after just a couple more simple clicks and about 4 minutes, WebMatrix 2 Beta was on my machine and open.&lt;/p&gt;  &lt;h3&gt;Creating the Web Site&lt;/h3&gt;  &lt;p&gt;I clicked on Templates and since this is going to be an extremely simple, one-page site, I went for the “Empty Site” template.  The Personal Site template was tempting, but over-the-top for my needs.  WebMatrix created the site in moments and then gave me a nice start page.  I immediately jumped to the “Files” view and here’s what I saw I was given:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/ASP.NET-Web-Pages-WebMatrix-Git-and-AppH_12A63/image_a65df55a-8427-4746-845c-60583b6159d7.png" width="302" height="458" /&gt;&lt;/p&gt;  &lt;p&gt;I created a new Popcorn.cshtml file that contains the content my son helped author.  It was a no-brainer to use the CSHTML file, as that lets me use the awesome Razor syntax as needed.  I created an /images folder and a /videos folder, where I put some media I had prepared.  Then I hit the Run button.  &lt;em&gt;Yes, I prefer Chrome.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/ASP.NET-Web-Pages-WebMatrix-Git-and-AppH_12A63/image_5029ba9c-361a-4fcc-8341-bf47ed4c4f5a.png" width="186" height="202" /&gt;&lt;/p&gt;  &lt;p&gt;Since I had added my content to Popcorn.cshtml, and hadn’t added anything to the Default.cshtml, I got a blank page.  That’s good with me, as a default page is out of scope for tonight’s project. :-)  What I really wanted to see is what I got when I browsed to /popcorn…&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/ASP.NET-Web-Pages-WebMatrix-Git-and-AppH_12A63/image_0324e3d1-1613-41c2-bc26-8e0ec872c577.png" width="690" height="297" /&gt;&lt;/p&gt;  &lt;p&gt;Perfect!  Notice that I didn’t have to browse to popcorn.cshtml – just /popcorn is sufficient because ASP.NET Web Pages automatically routes this form me.  That feels so much cleaner than creating a popcorn folder and adding a default.cshtml to it.  So, the website is now complete and ready for source control.&lt;/p&gt;  &lt;h3 /&gt;  &lt;h3&gt;Installing Git&lt;/h3&gt;  &lt;p&gt;github has an &lt;strong&gt;&lt;em&gt;awesome&lt;/em&gt;&lt;/strong&gt; page for setting up Git.  There’s no need for me to repeat anything here.  Just &lt;a href="http://help.github.com/win-set-up-git/" target="_blank"&gt;go to github’s page&lt;/a&gt; and then come back here when you’re ready. &lt;/p&gt;  &lt;h3&gt;Creating the Git Repository&lt;/h3&gt;  &lt;p&gt;This was easy stuff.  Using Git Bash, here’s what it took to initialize the Git repository, add the website, review the pending changes, and commit them.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/ASP.NET-Web-Pages-WebMatrix-Git-and-AppH_12A63/image_45bba832-ebc9-4b14-b090-4f4197a4a7a2.png" width="677" height="963" /&gt;&lt;/p&gt;  &lt;h3&gt;Deploying to AppHarbor&lt;/h3&gt;  &lt;p&gt;If you’re not familiar with &lt;a href="http://appharbor.com" target="_blank"&gt;AppHarbor&lt;/a&gt;, it’s a service that lets you host sites using Git to push a repository to the cloud (no, it’s not Azure – shame).  AppHarbor will host this site for free, which is a requirement for this project.  Signing up for AppHarbor was extremely simple and took about 1 minute.&lt;/p&gt;  &lt;p&gt;Before I could deploy, I needed to first create an application.  It’s a single-field form.  Seriously.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/ASP.NET-Web-Pages-WebMatrix-Git-and-AppH_12A63/image_61797304-8c08-4d44-a0f3-23f7e33cb940.png" width="291" height="230" /&gt;&lt;/p&gt;  &lt;p&gt;After naming the application and clicking Create, I was given idiot-proof instructions for how to set up a Git repository, configure it to push to AppHarbor, and do my first push.  Since I already initialized the repository, I skipped down to the “&lt;strong&gt;Add AppHarbor Repository and Push&lt;/strong&gt;” section.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/ASP.NET-Web-Pages-WebMatrix-Git-and-AppH_12A63/image_1b8411f7-d261-401f-961a-4bbbd80294c0.png" width="677" height="472" /&gt;&lt;/p&gt;  &lt;p&gt;At that point, the site was deployed to AppHarbor and running in the cloud.  Browsing to &lt;a href="http://xanderhandley.apphb.com/popcorn/"&gt;http://xanderhandley.apphb.com/popcorn/&lt;/a&gt; worked. I was close to finished; I just needed to set up the custom hostname.&lt;/p&gt;  &lt;h3&gt;Using a Custom Hostname&lt;/h3&gt;  &lt;p&gt;I wanted the site to have an easy URL, with &lt;a href="http://xanderhandley.com/popcorn"&gt;http://xanderhandley.com/popcorn&lt;/a&gt; as the goal.  Needless to say, I already own xanderhandley.com, so I just needed to point it to AppHarbor.  This was another single-field form on AppHarbor’s site, reached by clicking on the “Hostnames” menu link.&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/ASP.NET-Web-Pages-WebMatrix-Git-and-AppH_12A63/image_5feb993c-1196-45f8-b5e3-c7d41979da80.png" width="476" height="348" /&gt;&lt;/p&gt;  &lt;p&gt;Before hitting ‘Add hostname,’ I copied the IP address to my clipboard.  Then I went off to my DNS settings for the domain and configured an A record for the domain to point to that IP address.  After a few minutes of propagation, it worked.  &lt;a href="http://xanderhandley.com/popcorn"&gt;http://xanderhandley.com/popcorn&lt;/a&gt; loads the site I created in WebMatrix just 30 minutes ago, and Xander’s now able to sell popcorn online!&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:874ff272-99ec-4540-b2ba-bc10bc9b889e" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/WebMatrix" rel="tag"&gt;WebMatrix&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Git" rel="tag"&gt;Git&lt;/a&gt;,&lt;a href="http://technorati.com/tags/AppHarbor" rel="tag"&gt;AppHarbor&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/280.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/OcYmvXXTKAk" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/10/08/WebMatrix-Git-AppHarbor.aspx</guid>
            <pubDate>Sun, 09 Oct 2011 06:25:28 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/10/08/WebMatrix-Git-AppHarbor.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/280.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/10/08/WebMatrix-Git-AppHarbor.aspx</feedburner:origLink></item>
        <item>
            <title>RIA Services updates for //build</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/uiuTtQcvwJs/build.aspx</link>
            <description>&lt;p&gt;At //build, Dinesh Kulkarni from our team gave a presentation alongside Asad Khan from the OData team.  They showed RIA/JS consuming both a RIA Services DomainService as well as an OData feed from Azure.  Dinesh also showed RIA/JS working in the browser, in a Win8 Metro Style app, and on an iPhone using PhoneGap.  You can &lt;a href="http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-800T" target="_blank"&gt;watch their talk on Channel 9&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;To coincide with their talk, the RIA Services team published updates for RIA/JS:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Updated RIAServices.jQuery NuGet package &lt;/li&gt;    &lt;li&gt;New RIAServices.jQuery.Sample NuGet package &lt;/li&gt;    &lt;li&gt;WCF RIA Services Toolkit (September 2011) &lt;/li&gt;    &lt;li&gt;New RIA/JS landing page: &lt;a href="http://win8.ms/riajs"&gt;http://win8.ms/riajs&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;RIAServices.jQuery&lt;/h3&gt;  &lt;p&gt;&lt;em&gt;We are favoring NuGet over the MSI for toolkit components, as we can update the packages independently and more quickly.&lt;/em&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;&lt;i&gt;$.observable for data editing / change events&lt;/i&gt;&lt;/b&gt; – This is a prototype implementation of an observability pattern we’re working with the jQuery and jQuery UI teams on, following the pattern we’ve established with $.dataSource. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;&lt;i&gt;Query data from OData services&lt;/i&gt;&lt;/b&gt; – We’re now able to load / query / mash-up data from OData sources. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;&lt;i&gt;$.dataSource IntelliSense&lt;/i&gt;&lt;/b&gt; – You’ll now find detailed API guidance from the $.dataSource IntelliSense &lt;/li&gt;    &lt;li&gt;&lt;b&gt;&lt;i&gt;Simpler packaging / JavaScript classes/namespaces&lt;/i&gt;&lt;/b&gt; – RIA/JS now only has a single JavaScript file: &lt;em&gt;ria.js&lt;/em&gt;.  It contains classes like DataSource, DataContext, et al, and we’ve refined how we define classes and namespaces to follow common jQuery patterns. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;RIAServices.jQuery.Sample&lt;/h3&gt;  &lt;p&gt;Following the lead of the Entity Framework team, we’ve created a NuGet package that adds sample code into your project for using RIA/JS.  This is a great way to temporarily add sample code into your project, learn from it, and then uninstall it once you’ve implemented your own scenarios.  Give it a try!&lt;/p&gt;  &lt;h3&gt;WCF RIA Services Toolkit (September 2011)&lt;/h3&gt;  &lt;p&gt;The Toolkit has been updated to have the same content as the RIAServices.jQuery package.  There were no other updates to the Toolkit in this release.  You can always find the latest toolkit here: &lt;a href="http://jeffh.me/riatoolkit"&gt;http://jeffh.me/riatoolkit&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This Toolkit build works with both WCF RIA Services V1.0 &lt;a href="http://go.microsoft.com/fwlink/?LinkId=205085"&gt;SP1&lt;/a&gt; and the &lt;a href="http://go.microsoft.com/fwlink/?LinkId=215202"&gt;SP2&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Version Compatibility&lt;/h3&gt;  &lt;p&gt;With all of these new releases flying all around, it’s hard to know what works where. Hopefully this helps:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="1023"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="372"&gt;&lt;em&gt;Release&lt;/em&gt;&lt;/td&gt;        &lt;td valign="top" width="110"&gt;&lt;em&gt;Silverlight 4&lt;/em&gt;&lt;/td&gt;        &lt;td valign="top" width="145"&gt;&lt;em&gt;Silverlight 5&lt;/em&gt;&lt;/td&gt;        &lt;td valign="top" width="120"&gt;&lt;em&gt;RIA/JS&lt;/em&gt;&lt;/td&gt;        &lt;td valign="top" width="274"&gt;&lt;em&gt;Visual Studio 11 Developer Preview&lt;/em&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="372"&gt;&lt;strong&gt;WCF RIA Services V1.0 (RTM)&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="110"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;Yes&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="145"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;No&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="120"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;No&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="274"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;No&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="372"&gt;&lt;strong&gt;WCF RIA Services V1.0 SP1&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="110"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;Yes&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="145"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;No&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="120"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;No&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="274"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;No&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="372"&gt;&lt;strong&gt;WCF RIA Services V1.0 SP2 RC&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="110"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;Yes&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="145"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;Yes&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="120"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;Yes&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="274"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;No&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="372"&gt;&lt;strong&gt;WCF RIA Services Toolkit (September 2011)&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="110"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;Yes&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="145"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;Yes&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="120"&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;Yes&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="274"&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;No&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;strong&gt;At the time of WCF RIA Services V1.0 SP2 RC, Visual Studio 11 is not yet supported.  This is mostly because of our design-time components, and we are working to get that in place to offer VS11 support as soon as possible--stay tuned for updates therein.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;As you can see above, if you are building Silverlight 4 applications, you can use RIA Services V1.0 SP1 or SP2.  If you are developing Silverlight 5 applications though, you must use RIA Services V1.0 SP2.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cafb8d55-480a-426e-a491-a4c788fde6a8" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/RIAServices" rel="tag"&gt;RIAServices&lt;/a&gt;,&lt;a href="http://technorati.com/tags/jQuery" rel="tag"&gt;jQuery&lt;/a&gt;,&lt;a href="http://technorati.com/tags/OData" rel="tag"&gt;OData&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/279.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/uiuTtQcvwJs" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/09/16/build.aspx</guid>
            <pubDate>Sat, 17 Sep 2011 01:07:51 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/09/16/build.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/279.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/09/16/build.aspx</feedburner:origLink></item>
        <item>
            <title>RIA Services Validation: Available on GitHub</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/P-5Pt85MlX8/RIA-Services-Validation-Available-on-GitHub.aspx</link>
            <description>&lt;p&gt;I’ve gotten quite a few requests for the source code behind the RIA Services Validation blog post series.  I am pleased to announce that the code is now published on GitHub.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://github.com/jeffhandley/RIAServicesValidation"&gt;http://github.com/jeffhandley/RIAServicesValidation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Within that repository, you’ll find:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;RudeValidation.Web/Models – Server-side model classes &lt;/li&gt;    &lt;li&gt;RudeValidation.Web/Validators – Custom validators including CompareValidator, ConditionallyRequired, and DateValidator &lt;/li&gt;    &lt;li&gt;RudeValidation/Views – Sample screens showing the validation in action &lt;/li&gt;    &lt;li&gt;RudeValidation/ViewModels - Where you’ll find the sample ViewModel as well as the very simple ViewModelBase &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;If you’re not familiar with Git, don’t be intimidated.  You can easily view the code directly in your browser by starting out at &lt;a href="http://github.com/jeffhandley/RIAServicesValidation"&gt;http://github.com/jeffhandley/RIAServicesValidation&lt;/a&gt; and just clicking through the folders and files.  To download all of the source, just click the Downloads button, and click to download the Zip file.  As always when downloading a Zip from the tubes, be sure to Unblock the Zip file through the Properties window before you extract the contents.  Then, be sure to set the RudeValidation.Web project as the startup.  After that, you are welcome to do whatever you want with the source code included.&lt;/p&gt;  &lt;h3&gt;RIA Services Validation Recap&lt;/h3&gt;  &lt;p&gt;Over the course of a 10-post series, we learned about the standard validators, how to create different types of custom validators, how the validation attributes get propagated, how to perform common cross-field and cross-entity validation, and now we have a utility for importing model rules into ViewModel classes.  Here’s the full series:&lt;/p&gt;  &lt;ol&gt;   &lt;ol&gt;     &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/09/22/RiaServicesStandardValidators.aspx"&gt;Standard Validators&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/09/25/RiaServicesCustomValidationMethods.aspx"&gt;Custom Validation Methods&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/09/26/RiaServicesCustomReusableValidators.aspx"&gt;Custom Reusable Validators&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/09/30/RiaServicesValidationAttributePropagation.aspx"&gt;Attribute Propagation&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/06/RiaServicesValidationTriggers.aspx"&gt;Validation Triggers&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/10/CrossFieldValidation.aspx"&gt;Cross-Field Validation&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/12/EntityLevelValidation.aspx"&gt;Entity-Level Validation&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/25/RiaServicesValidationContext.aspx"&gt;Providing ValidationContext&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/25/CrossEntityValidation.aspx"&gt;Using ValidationContext (Cross-Entity Validation)&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2011/09/06/ViewModelValidation.aspx"&gt;ViewModel Validation with Entity Rules&lt;/a&gt; &lt;/li&gt;   &lt;/ol&gt; &lt;/ol&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:be6e2704-e6cc-450a-90ad-270c0757e8ac" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/RiaServicesValidation" rel="tag"&gt;RiaServicesValidation&lt;/a&gt;,&lt;a href="http://technorati.com/tags/RIAServices" rel="tag"&gt;RIAServices&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Validation" rel="tag"&gt;Validation&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;,&lt;a href="http://technorati.com/tags/DataAnnotations" rel="tag"&gt;DataAnnotations&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/278.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/P-5Pt85MlX8" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/09/06/RIA-Services-Validation-Available-on-GitHub.aspx</guid>
            <pubDate>Wed, 07 Sep 2011 06:50:15 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/09/06/RIA-Services-Validation-Available-on-GitHub.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/278.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/09/06/RIA-Services-Validation-Available-on-GitHub.aspx</feedburner:origLink></item>
        <item>
            <title>RIA Services Validation: ViewModel Validation with Entity Rules</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/9_LRj0iFDR8/ViewModelValidation.aspx</link>
            <description>&lt;p&gt;For those of you familiar with the ViewModel (or MVVM) pattern, you are likely also familiar with a typical pain point regarding validation: you often need to duplicate your entity validation metadata onto your ViewModel classes.  This can lead to burdensome dual maintenance of your validation rules, and it can seem very frustrating that with the server to client metadata propagation that RIA Services offers, your ViewModel classes are left dangling out there for you to manage yourself.  In this post, I’ll illustrate a utility I created that allows a ViewModel to assume validation metadata from model classes or properties, eliminating the dual maintenance.&lt;/p&gt;  &lt;h3&gt;ModelPropertyValidator&lt;/h3&gt;  &lt;p&gt;Virtually every ViewModel will have properties that actually represent properties from your model.  Let’s use the meeting invitation model from earlier RIA Services Validation posts as an example.  My meeting object has a bunch of properties such as Title, Start, End, Location, MinimumAttendees, MaximumAttendees, and Details.  It’s easy to imagine a ViewModel that could be used for managing meetings where the UI would have a subset or superset of the meeting properties.  For each field on the screen that represents a meeting property, I should be able to indicate which model property is associated with each ViewModel property so that the model validation can be imported automatically.  This is where ModelPropertyValidator comes in.&lt;/p&gt;  &lt;p&gt;Here’s a subset of the Meeting class with its data annotations in my Web project:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:659c81d7-43aa-4cca-9634-9279487f2263" class="wlWriterSmartContent"&gt;   &lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;     &lt;div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px"&gt;Code Snippet&lt;/div&gt;      &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt;       &lt;ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px"&gt;         &lt;li&gt;[&lt;span style="color: #2b91af"&gt;CustomValidation&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;MeetingValidators&lt;/span&gt;), &lt;span style="color: #a31515"&gt;"PreventExpensiveMeetings"&lt;/span&gt;)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;[&lt;span style="color: #2b91af"&gt;CustomValidation&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;MeetingValidators&lt;/span&gt;), &lt;span style="color: #a31515"&gt;"PreventDoubleBooking"&lt;/span&gt;)] &lt;/li&gt;          &lt;li&gt;[&lt;span style="color: #2b91af"&gt;MetadataType&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Meeting&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;MeetingMetadata&lt;/span&gt;))] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Meeting&lt;/span&gt; &lt;/li&gt;          &lt;li&gt;{ &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MeetingMetadata&lt;/span&gt; &lt;/li&gt;          &lt;li&gt;    { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        [&lt;span style="color: #2b91af"&gt;Key&lt;/span&gt;] &lt;/li&gt;          &lt;li&gt;        [&lt;span style="color: #2b91af"&gt;Display&lt;/span&gt;(AutoGenerateField = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MeetingId { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        [&lt;span style="color: #2b91af"&gt;Required&lt;/span&gt;] &lt;/li&gt;          &lt;li&gt;        [&lt;span style="color: #2b91af"&gt;CustomValidation&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;MeetingValidators&lt;/span&gt;), &lt;span style="color: #a31515"&gt;"NoEarlyMeetings"&lt;/span&gt;)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        [&lt;span style="color: #2b91af"&gt;CompareValidator&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CompareOperator&lt;/span&gt;.LessThan, &lt;span style="color: #a31515"&gt;"End"&lt;/span&gt;, &lt;/li&gt;          &lt;li&gt;            ErrorMessage = &lt;span style="color: #a31515"&gt;"Meetings cannot result in time travel."&lt;/span&gt;)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        [&lt;span style="color: #2b91af"&gt;DateValidator&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DateValidatorType&lt;/span&gt;.Future)] &lt;/li&gt;          &lt;li&gt;        [&lt;span style="color: #2b91af"&gt;Display&lt;/span&gt;(Order = 1)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt; Start { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        [&lt;span style="color: #2b91af"&gt;Required&lt;/span&gt;] &lt;/li&gt;          &lt;li&gt;        [&lt;span style="color: #2b91af"&gt;CompareValidator&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CompareOperator&lt;/span&gt;.GreaterThan, &lt;span style="color: #a31515"&gt;"Start"&lt;/span&gt;, &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            ErrorMessage = &lt;span style="color: #a31515"&gt;"Meetings cannot result in time travel."&lt;/span&gt;)] &lt;/li&gt;          &lt;li&gt;        [&lt;span style="color: #2b91af"&gt;Display&lt;/span&gt;(Order = 2)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt; End { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        [&lt;span style="color: #2b91af"&gt;Required&lt;/span&gt;] &lt;/li&gt;          &lt;li&gt;        [&lt;span style="color: #2b91af"&gt;StringLength&lt;/span&gt;(80, MinimumLength = 5, &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            ErrorMessageResourceType = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ValidationErrorResources&lt;/span&gt;), &lt;/li&gt;          &lt;li&gt;            ErrorMessageResourceName = &lt;span style="color: #a31515"&gt;"TitleStringLengthErrorMessage"&lt;/span&gt;)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #008000"&gt;// {0} must be at least {2} characters and no more than {1}.&lt;/span&gt; &lt;/li&gt;          &lt;li&gt;        [&lt;span style="color: #2b91af"&gt;Display&lt;/span&gt;(Order = 0)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Title { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; } &lt;/li&gt;       &lt;/ol&gt;     &lt;/div&gt;   &lt;/div&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;When a ViewModel is going to expose the Start property for a meeting, it would be a nightmare to have to keep all of the validation attributes in sync.  To alleviate this, I created an attribute called ModelPropertyValidatorAttribute that acts as a proxy from a ViewModel property to a Model property.  Here’s what it looks like to use it:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:94bcf9a7-a2a1-4503-84cd-8b04b8958344" class="wlWriterSmartContent"&gt;   &lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;     &lt;div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px"&gt;Code Snippet&lt;/div&gt;      &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt;       &lt;ol style="padding-bottom: 0px; margin: 0px 0px 0px 2.5em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px"&gt;         &lt;li&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MeetingEntryViewModel&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;ViewModelBase&lt;/span&gt; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;{ &lt;/li&gt;          &lt;li&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt; start; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt; end; &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    [&lt;span style="color: #2b91af"&gt;ModelPropertyValidator&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Meeting&lt;/span&gt;))] &lt;/li&gt;          &lt;li&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt; Start &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    { &lt;/li&gt;          &lt;li&gt;        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.start; } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; &lt;/li&gt;          &lt;li&gt;        { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.start != &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) &lt;/li&gt;          &lt;li&gt;            { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ValidateProperty(&lt;span style="color: #a31515"&gt;"Start"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;); &lt;/li&gt;          &lt;li&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.start = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.RaisePropertyChanged(&lt;span style="color: #a31515"&gt;"Start"&lt;/span&gt;); &lt;/li&gt;          &lt;li&gt;            } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        } &lt;/li&gt;          &lt;li&gt;    } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;    [&lt;span style="color: #2b91af"&gt;ModelPropertyValidator&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Meeting&lt;/span&gt;))] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt; End &lt;/li&gt;          &lt;li&gt;    { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.end; } &lt;/li&gt;          &lt;li&gt;        &lt;span style="color: #0000ff"&gt;set&lt;/span&gt; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        { &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.end != &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            { &lt;/li&gt;          &lt;li&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ValidateProperty(&lt;span style="color: #a31515"&gt;"End"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.end = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; &lt;/li&gt;          &lt;li&gt;                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.RaisePropertyChanged(&lt;span style="color: #a31515"&gt;"End"&lt;/span&gt;); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            } &lt;/li&gt;          &lt;li&gt;        } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    } &lt;/li&gt;          &lt;li&gt;} &lt;/li&gt;       &lt;/ol&gt;     &lt;/div&gt;   &lt;/div&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;With a simple attribute on each, the Start and End properties now import all of the validation attributes from their corresponding Model properties on the Meeting type; no more validation duplication!  When the property name is the same on the Model and the ViewModel, you can get away with only specifying the model type, but I also have an overload that accepts the model property name in case the property names differ.&lt;/p&gt;  &lt;h3&gt;ModelObjectValidator&lt;/h3&gt;  &lt;p&gt;Just as there are cases when you want a ViewModel property to import the validation attributes from a model property, there are also times when you want a ViewModel class to import a model’s object-level validation attributes.  That’s where ModelObjectValidatorAttribute comes in.  Very similarly to the ModelPropertyValidator, you just put the attribute on the ViewModel and specify the corresponding model type.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:57b45adf-a303-46cf-85ef-8bdc59e3e945" class="wlWriterSmartContent"&gt;   &lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;     &lt;div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px"&gt;Code Snippet&lt;/div&gt;      &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt;       &lt;ol style="padding-bottom: 0px; margin: 0px 0px 0px 2em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px"&gt;         &lt;li&gt;[&lt;span style="color: #2b91af"&gt;ModelObjectValidator&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Meeting&lt;/span&gt;))] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MeetingEntryViewModel&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;ViewModelBase&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IStartAndEnd&lt;/span&gt; &lt;/li&gt;          &lt;li&gt;{ &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt; start; &lt;/li&gt;          &lt;li&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DateTime&lt;/span&gt; end; &lt;/li&gt;       &lt;/ol&gt;     &lt;/div&gt;   &lt;/div&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;That’s all there is to it.  Now the MeetingEntryViewModel class imports the object-level validation from the Meeting type.  You can even specify multiple ModelObjectValidator attributes if you want to import validation attributes from multiple classes.&lt;/p&gt;  &lt;h3&gt;How’d you do that?&lt;/h3&gt;  &lt;p&gt;Here’s how it works:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;ModelPropertyValidatorAttribute and ModelObjectValidatorAttribute both derive from ModelValidatorAttribute &lt;/li&gt;    &lt;li&gt;ModelValidatorAttribute is an abstract class that derives from ValidationAttribute &lt;/li&gt;    &lt;li&gt;ModelValidatorAttribute overrides IsValid and performs much of the same work that Validator performs, iterating over the attributes on the target and producing validation errors as ValidationResult instances &lt;/li&gt;    &lt;li&gt;If the ViewModel derives from the RIA Services ComplexObject class, then there’s a nice ValidationErrors property that can be used to add multiple error messages &lt;/li&gt;    &lt;li&gt;Otherwise, the first validation error is returned as the error message from this custom validator &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Yes, I suggested that you make your ViewModel classes derive from ComplexObject.  ComplexObject is a really useful class and it exposes a great ValidationErrors collection that any consumer can manipulate, and all updates to that collection generate events from the INotifyDataErrorInfo interface.  This works perfectly for this scenario where I want my validation attribute to be able to push multiple validation results onto the target object, despite the fact that the IsValid method is only capable of returning a single error.&lt;/p&gt;  &lt;p&gt;Here’s the full code for the ModelValidatorAttribute and the two derived forms.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ca92c7da-44b2-4888-af78-92f7747b492c" class="wlWriterSmartContent"&gt;   &lt;div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: 'Courier New', courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"&gt;     &lt;div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: verdana, tahoma, arial, sans-serif; background: #000080; color: #fff; font-weight: bold; padding-top: 2px"&gt;Code Snippet&lt;/div&gt;      &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt;       &lt;ol style="padding-bottom: 0px; margin: 0px 0px 0px 3em; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px"&gt;         &lt;li&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;/li&gt;          &lt;li&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ComponentModel.DataAnnotations; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Linq; &lt;/li&gt;          &lt;li&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Reflection; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ServiceModel.DomainServices.Client; &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; RudeValidation.Helpers &lt;/li&gt;          &lt;li&gt;{ &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelPropertyValidatorAttribute&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;ModelValidatorAttribute&lt;/span&gt; &lt;/li&gt;          &lt;li&gt;    { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ModelPropertyValidatorAttribute(&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; modelType) &lt;/li&gt;          &lt;li&gt;            : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(modelType, &lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt;.InferProperty) { } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ModelPropertyValidatorAttribute(&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; modelType, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; propertyName) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(modelType, propertyName) { } &lt;/li&gt;          &lt;li&gt;    } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelObjectValidatorAttribute&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;ModelValidatorAttribute&lt;/span&gt; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    { &lt;/li&gt;          &lt;li&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ModelObjectValidatorAttribute(&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; modelType) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(modelType, &lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt;.Object) { } &lt;/li&gt;          &lt;li&gt;    } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;    [&lt;span style="color: #2b91af"&gt;AttributeUsage&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;AttributeTargets&lt;/span&gt;.Property | &lt;span style="color: #2b91af"&gt;AttributeTargets&lt;/span&gt;.Class | &lt;span style="color: #2b91af"&gt;AttributeTargets&lt;/span&gt;.Parameter, AllowMultiple = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)] &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelValidatorAttribute&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;ValidationAttribute&lt;/span&gt; &lt;/li&gt;          &lt;li&gt;    { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; ModelType { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; } &lt;/li&gt;          &lt;li&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt; ValidationMode { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ModelProperty { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; model; &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ModelValidatorAttribute(&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; modelType, &lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt; validationMode) &lt;/li&gt;          &lt;li&gt;        { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ModelType = modelType; &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ValidationMode = validationMode; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ModelValidatorAttribute(&lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; modelType, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; modelPropertyName) &lt;/li&gt;          &lt;li&gt;        { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ModelType = modelType; &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ValidationMode = Helpers.&lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt;.SpecifiedProperty; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ModelProperty = modelPropertyName; &lt;/li&gt;          &lt;li&gt;        } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt; IsValid(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; value, &lt;span style="color: #2b91af"&gt;ValidationContext&lt;/span&gt; validationContext) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        { &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (model == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            { &lt;/li&gt;          &lt;li&gt;                model = &lt;span style="color: #2b91af"&gt;Activator&lt;/span&gt;.CreateInstance(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ModelType); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #2b91af"&gt;ValidationContext&lt;/span&gt; redirectedContext = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ValidationContext&lt;/span&gt;(model, validationContext, validationContext.Items); &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ValidationMode) &lt;/li&gt;          &lt;li&gt;            { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt;.InferProperty: &lt;/li&gt;          &lt;li&gt;                    redirectedContext.MemberName = validationContext.MemberName; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;; &lt;/li&gt;          &lt;li&gt;                &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt;.SpecifiedProperty: &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    redirectedContext.MemberName = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ModelProperty; &lt;/li&gt;          &lt;li&gt;                    &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt;.Object: &lt;/li&gt;          &lt;li&gt;                    redirectedContext.MemberName = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;; &lt;/li&gt;          &lt;li&gt;            } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #2b91af"&gt;ComplexObject&lt;/span&gt; targetEntity = validationContext.ObjectInstance &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ComplexObject&lt;/span&gt;; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; breakOnFirstError = (targetEntity == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;); &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;&amp;gt; validationResults = TryValidateProperty(value, validationContext, redirectedContext, breakOnFirstError); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (validationResults.Any()) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            { &lt;/li&gt;          &lt;li&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (validationResults.Count() == 1) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                { &lt;/li&gt;          &lt;li&gt;                    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; validationResults.Single(); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (targetEntity != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &lt;/li&gt;          &lt;li&gt;                { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt; result &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; validationResults.Skip(1)) &lt;/li&gt;          &lt;li&gt;                    { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                        targetEntity.ValidationErrors.Add(result); &lt;/li&gt;          &lt;li&gt;                    } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; validationResults.First(); &lt;/li&gt;          &lt;li&gt;            } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;.Success; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;&amp;gt; TryValidateProperty(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; value, &lt;span style="color: #2b91af"&gt;ValidationContext&lt;/span&gt; validationContext, &lt;span style="color: #2b91af"&gt;ValidationContext&lt;/span&gt; modelValidationContext, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; breakOnFirstError) &lt;/li&gt;          &lt;li&gt;        { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #2b91af"&gt;ICustomAttributeProvider&lt;/span&gt; validatorProvider; &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(modelValidationContext.MemberName)) &lt;/li&gt;          &lt;li&gt;            { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                validatorProvider = modelValidationContext.ObjectType.GetProperty(modelValidationContext.MemberName); &lt;/li&gt;          &lt;li&gt;            } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;/li&gt;          &lt;li&gt;            { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                validatorProvider = modelValidationContext.ObjectType; &lt;/li&gt;          &lt;li&gt;            } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationAttribute&lt;/span&gt;&amp;gt; validators = validatorProvider &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                .GetCustomAttributes(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ValidationAttribute&lt;/span&gt;), &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;) &lt;/li&gt;          &lt;li&gt;                .Cast&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationAttribute&lt;/span&gt;&amp;gt;(); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;&amp;gt; results = GetValidationErrors(value, validationContext, validators, breakOnFirstError); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; results; &lt;/li&gt;          &lt;li&gt;        } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;&amp;gt; GetValidationErrors(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; value, &lt;span style="color: #2b91af"&gt;ValidationContext&lt;/span&gt; validationContext, &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationAttribute&lt;/span&gt;&amp;gt; attributes, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; breakOnFirstError) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        { &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;&amp;gt; errors = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;&amp;gt;(); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; hasErrors = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;; &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt; result; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;RequiredAttribute&lt;/span&gt; required &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; attributes.OfType&amp;lt;&lt;span style="color: #2b91af"&gt;RequiredAttribute&lt;/span&gt;&amp;gt;()) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            { &lt;/li&gt;          &lt;li&gt;                result = required.GetValidationResult(value, validationContext); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (result != &lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;.Success) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                { &lt;/li&gt;          &lt;li&gt;                    errors.Add(result); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    hasErrors = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (breakOnFirstError) &lt;/li&gt;          &lt;li&gt;                    { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; errors; &lt;/li&gt;          &lt;li&gt;                    } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                } &lt;/li&gt;          &lt;li&gt;            } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (hasErrors) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            { &lt;/li&gt;          &lt;li&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; errors; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            } &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ValidationAttribute&lt;/span&gt; attribute &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; attributes) &lt;/li&gt;          &lt;li&gt;            { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (attribute &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RequiredAttribute&lt;/span&gt;) &lt;/li&gt;          &lt;li&gt;                { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color: #0000ff"&gt;continue&lt;/span&gt;; &lt;/li&gt;          &lt;li&gt;                } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;                result = attribute.GetValidationResult(value, validationContext); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (result != &lt;span style="color: #2b91af"&gt;ValidationResult&lt;/span&gt;.Success) &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                { &lt;/li&gt;          &lt;li&gt;                    errors.Add(result); &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    hasErrors = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;; &lt;/li&gt;          &lt;li&gt;  &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (breakOnFirstError) &lt;/li&gt;          &lt;li&gt;                    { &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; errors; &lt;/li&gt;          &lt;li&gt;                    } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;                } &lt;/li&gt;          &lt;li&gt;            } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; errors; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        } &lt;/li&gt;          &lt;li&gt;    } &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;  &lt;/li&gt;          &lt;li&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;enum&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ModelValidationMode&lt;/span&gt; &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    { &lt;/li&gt;          &lt;li&gt;        InferProperty, &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;        SpecifiedProperty, &lt;/li&gt;          &lt;li&gt;        Object &lt;/li&gt;          &lt;li style="background: #f3f3f3"&gt;    } &lt;/li&gt;          &lt;li&gt;} &lt;/li&gt;       &lt;/ol&gt;     &lt;/div&gt;   &lt;/div&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h3&gt;RIA Services Validation Recap&lt;/h3&gt;  &lt;p&gt;This was the 10th installment in a blog post series about RIA Services Validation.  We’ve learned about the standard validators, how to create different types of custom validators, how the validation attributes get propagated, how to perform common cross-field and cross-entity validation, and now we have a utility for importing model rules into ViewModel classes.  Here’s the full series:&lt;/p&gt;  &lt;ol&gt;   &lt;ol&gt;     &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/09/22/RiaServicesStandardValidators.aspx"&gt;Standard Validators&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/09/25/RiaServicesCustomValidationMethods.aspx"&gt;Custom Validation Methods&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/09/26/RiaServicesCustomReusableValidators.aspx"&gt;Custom Reusable Validators&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/09/30/RiaServicesValidationAttributePropagation.aspx"&gt;Attribute Propagation&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/06/RiaServicesValidationTriggers.aspx"&gt;Validation Triggers&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/10/CrossFieldValidation.aspx"&gt;Cross-Field Validation&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/12/EntityLevelValidation.aspx"&gt;Entity-Level Validation&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/25/RiaServicesValidationContext.aspx"&gt;Providing ValidationContext&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2010/10/25/CrossEntityValidation.aspx"&gt;Using ValidationContext (Cross-Entity Validation)&lt;/a&gt; &lt;/li&gt;      &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2011/09/06/ViewModelValidation.aspx"&gt;ViewModel Validation with Entity Rules&lt;/a&gt; &lt;/li&gt;   &lt;/ol&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;The source code for everything shown during the series is &lt;a href="http://jeffhandley.com/archive/2011/09/06/RIA-Services-Validation-Available-on-GitHub.aspx"&gt;available on GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:44bf9f0c-64be-43cb-8967-e2ec437badea" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/RiaServicesValidation" rel="tag"&gt;RiaServicesValidation&lt;/a&gt;,&lt;a href="http://technorati.com/tags/RIAServicesValidation" rel="tag"&gt;RIAServicesValidation&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Validation" rel="tag"&gt;Validation&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;,&lt;a href="http://technorati.com/tags/DataAnnotations" rel="tag"&gt;DataAnnotations&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/277.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/9_LRj0iFDR8" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/09/06/ViewModelValidation.aspx</guid>
            <pubDate>Wed, 07 Sep 2011 06:31:01 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/09/06/ViewModelValidation.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/277.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/09/06/ViewModelValidation.aspx</feedburner:origLink></item>
        <item>
            <title>Business Application Project Login / Registration Disables Everything</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/an34ZMsaleI/BATDisabled.aspx</link>
            <description>&lt;p&gt;There is a known issue with WCF RIA Services V1.0 SP2 RC’s Business Application project template.  The issue only surfaces in Silverlight 5, and there’s an easy way to fix it.  We determined the root cause of this issue after it was too late to fix it in time for the RC release, but the correction is in place for the RTW (final) release of SP2.&lt;/p&gt;  &lt;p&gt;This bug surfaces after you create a new project after installing RIA Services SP2, using the Business Application project template, and then an end user registers or logs in.  After completing the registration/login process, the entire application is disabled.  You can see the Home, About, and logout buttons are disabled, and nothing is clickable.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/84403f50f45e_D26D/image_2.png" rel="lightbox"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/84403f50f45e_D26D/image_thumb.png" width="215" height="87" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If you change the project to target Silverlight 4, the problem goes away.  This made us think the problem was in the Silverlight runtime or SDK, but after the Silverlight team investigated it, the root cause ended up being in the project template within the code we put in place to help you get started.&lt;/p&gt;  &lt;p&gt;It boils down to the LoginRegistrationWindow.xaml.cs file that is included in the template under the Views\Login folder in the Silverlight project.  Within that file, the OnOpened method from ChildWindow is overridden:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:47557551-dd3f-4dd6-84c2-a32a63571edc" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Ensures the visual state and focus are correct when the window is opened.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; OnOpened()&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.NavigateToLogin();&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;The problem is that in this override, the code does not call base.OnOpened().  When targeting the Silverlight 4 SDK, this just happens to work out okay and the screen gets re-enabled, but when targeting the Silverlight 5 SDK, a change to ChildWindow makes this misuse lead to a disabled screen.  By simply adding base.OnOpened before this.NavigateToLogin(), the problem goes away.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:96285032-e2b4-4401-a8dc-007bd355571c" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Ensures the visual state and focus are correct when the window is opened.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; OnOpened()&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;.OnOpened();&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.NavigateToLogin();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;With that fix in place, you can register/log in and the app will return to normal.  This same problem exists for the VB version of the template. You would need to a call to MyBase.OnOpened() to fix the problem.  Here’s what the Home, About, and logout links will look after applying the fix.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/84403f50f45e_D26D/image_4.png" rel="lightbox"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://jeffhandley.com/images/jeffhandley_com/Windows-Live-Writer/84403f50f45e_D26D/image_thumb_1.png" width="215" height="87" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cb41d64d-e464-4752-8d71-230a82afd98f" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/RIAServices" rel="tag"&gt;RIAServices&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/276.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/an34ZMsaleI" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/09/03/BATDisabled.aspx</guid>
            <pubDate>Sat, 03 Sep 2011 22:42:56 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/09/03/BATDisabled.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/276.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/09/03/BATDisabled.aspx</feedburner:origLink></item>
        <item>
            <title>WCF RIA Services V1.0 SP2 RC</title>
            <link>http://feeds.jeffhandley.com/~r/JeffHandley/~3/Rh6MQYkvDRY/RIAServicesSP2RC.aspx</link>
            <description>&lt;p&gt;On September 1, 2011, Silverlight 5 RC was released.  As always, RIA Services is included in the Tools for Silverlight, and that release included our V1.0 SP2 RC build.  And also as always, we published a standalone installer for RIA Services.  You can find it &lt;a href="http://go.microsoft.com/fwlink/?LinkID=227926"&gt;on the download center&lt;/a&gt;.  The &lt;a href="http://silverlight.net/getstarted/riaservices"&gt;silverlight.net/getstarted/riaservices&lt;/a&gt; page will get updated soon to include the link to this build.&lt;/p&gt;  &lt;p&gt;This release is one more step toward closing down our SP2 release, and we fixed a number of bugs since SP1.  Some notable differences between SP1 and SP2 are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;DateTimeOffset is supported in SP2 &lt;/li&gt;    &lt;li&gt;Support for Silverlight 5 (see below) &lt;/li&gt;    &lt;li&gt;Entity Framework Code-First Support (see below) &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2011/08/08/LiveIntelliSenseDeprecated.aspx"&gt;Live IntelliSense is deprecated&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://varunpuranik.wordpress.com/2011/06/14/operationtagits-demise-and-workarounds/"&gt;OperationTag was removed&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Support for Silverlight 5 (and Silverlight 4)&lt;/h3&gt;  &lt;p&gt;If you’re using RIA Services SP1, you can target Silverlight 5 with your applications and everything will seem to work.  Unfortunately, there’s a small issue that is lurking in your generated code, ready and waiting to cause you bugs.  If you look closely at differences between SL4 and SL5 code, you’ll see that there RIA Services SP1 never generates a [RoundtripOriginal] attribute.  The omission of this attribute can wreak havoc on your application, and it’s unfortunate that it is silently omitted.  With RIA Services SP2, the attribute will return when you are targeting Silverlight 5, and your app will be back to normal.&lt;/p&gt;  &lt;p&gt;This issue was introduced because Silverlight 5 changed the runtime and SDK assembly versions from 2.0.5.0 to 5.0.5.0.  Deep down in the RIA Services code generation layer, this caused problems where Silverlight assemblies with the 2.0.5.0 version on them could not be loaded.  Ultimately, that surfaced as attributes from those assemblies not getting propagated from the server to the client.  Because RoundtripOriginalAttribute is defined in a SL4-based assembly, it fails to get generated when targeting Silverlight 5.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;We fixed this issue in RIA Services SP2, so if you are targeting Silverlight 5, you must use RIA Services SP2.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In addition to using RIA Services SP2 for Silverlight 5 applications, &lt;strong&gt;&lt;u&gt;you can still target Silverlight 4 as well&lt;/u&gt;&lt;/strong&gt;.  RIA Services does not depend on Silverlight 5 at all and is in fact still compiled against Silverlight 4 to ensure backward-compatibility.&lt;/p&gt;  &lt;h3&gt;Entity Framework Code First Support&lt;/h3&gt;  &lt;p&gt;Support for Entity Framework Code First is provided through either the RIA Services Toolkit, or through the RIAServices.EntityFramework NuGet package.  Rather than repeating myself, I’ll just point you to some previous posts on this topic:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2011/06/30/RIAServicesCodeFirst.aspx"&gt;RIA Services EF Code First Support&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeffhandley.com/archive/2011/08/02/ToolkitAugust2011.aspx"&gt;WCF RIA Services Toolkit (August 2011) - And Updated NuGet Packages&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The difference that you’ll see with the SP2 RC release though is that EF Code First DbContext classes are now respected by the Domain Service Wizard when using “Add New Item… Domain Service.”  When you have a valid DbContext class, and you have the Microsoft.ServiceModel.DomainServices.EntityFramework assembly referenced (either from the Toolkit or NuGet), you can now select it from the drop-down and have your Domain Service class stubbed out for you.&lt;/p&gt;  &lt;p&gt;For more info on how to use EF Code First with RIA Services, &lt;a href="http://varunpuranik.wordpress.com/2011/06/29/wcf-ria-services-support-for-ef-4-1-and-ef-code-first/"&gt;please check out Varun Puranik’s blog&lt;/a&gt;.  But again, with SP2 RC, you’ll get Domain Service wizard support. Yeah!  But don’t forget you need to add the reference to the Toolkit assembly or (preferably) the RIAServices.EntityFramework NuGet package in order for it to light up.&lt;/p&gt;  &lt;h3&gt;Side by Side Support?&lt;/h3&gt;  &lt;p&gt;Some people have asked me if RIA Services supports Side-by-Side installations.  No, it doesn’t.  If you’re targeting Silverlight 4 and you need a Go-Live license, use RIA Services V1.0 SP1.  If you’re targeting Silverlight 5 or you don’t need a Go-Live license, then use RIA Services V1.0 SP2.&lt;/p&gt;  &lt;p&gt;Something else I wanted to mention regarding side-by-side support is Silverlight 4 and Silverlight 5.  There’s an important detail that I don’t know has been communicated properly: When installing Silverlight 5 on your machine, you &lt;em&gt;must&lt;/em&gt; keep the Silverlight 4 SDK and Tools installed on your machine.  For that matter, you need to keep the Silverlight 3 SDK installed too.  If you uninstall any of those things, I promise you pain.  Installing Silverlight 5 RC Tools will give you the Silverlight 5 runtime, SDK, and Tools.  Your Silverlight 3/4 SDK/Tools will be left in place as these function side-by-side.  Your Silverlight runtime will be replaced with SL5, but that won’t interrupt SL4 work.&lt;/p&gt;  &lt;h3&gt;Roadmap&lt;/h3&gt;  &lt;p&gt;We are getting close to a final release of SP2.  You can expect our final release to be included with Silverlight 5’s final release.  We are listening for feedback on the RC though, and we look forward to getting the RTW build in your hands soon!&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:560df27e-2d10-481d-8733-9abc250b15aa" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/RIAServices" rel="tag"&gt;RIAServices&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;,&lt;a href="http://technorati.com/tags/EntityFramework" rel="tag"&gt;EntityFramework&lt;/a&gt;&lt;/div&gt;&lt;img src="http://jeffhandley.com/aggbug/274.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/JeffHandley/~4/Rh6MQYkvDRY" height="1" width="1"/&gt;</description>
            <dc:creator>Jeff Handley</dc:creator>
            <guid isPermaLink="false">http://jeffhandley.com/archive/2011/09/02/RIAServicesSP2RC.aspx</guid>
            <pubDate>Sat, 03 Sep 2011 01:25:26 GMT</pubDate>
            <comments>http://jeffhandley.com/archive/2011/09/02/RIAServicesSP2RC.aspx#feedback</comments>
            <slash:comments>11</slash:comments>
            <wfw:commentRss>http://jeffhandley.com/comments/commentRss/274.aspx</wfw:commentRss>
        <feedburner:origLink>http://jeffhandley.com/archive/2011/09/02/RIAServicesSP2RC.aspx</feedburner:origLink></item>
    </channel>
</rss>

