<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" 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:image="http://purl.org/rss/1.0/modules/image/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>Paraesthesia</title>
        <link>http://www.paraesthesia.com/Default.aspx</link>
        <description>.NET Development and Some Pictures of My Cat</description>
        <language>en-US</language>
        <copyright>Travis Illig</copyright>
        <generator>Subtext Version 2.5.2.0</generator>
        <image>
            <title>Paraesthesia</title>
            <url>http://www.paraesthesia.com/images/RSS2Image.gif</url>
            <link>http://www.paraesthesia.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.feedburner.com/Paraesthesia" /><feedburner:info uri="paraesthesia" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>45.545841</geo:lat><geo:long>-122.946059</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><feedburner:emailServiceId>Paraesthesia</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
            <title>Setting DependentUpon File Properties on NuGet Package Install</title>
            <category>.NET</category>
            <category>Visual Studio</category>
            <link>http://feedproxy.google.com/~r/Paraesthesia/~3/DL-m_JqefzY/setting-dependentupon-file-properties-on-nuget-package-install.aspx</link>
            <description>&lt;p&gt;In working on some NuGet packages, one thing I wanted to do was set up some configuration files in preparation for &lt;a href="http://nuget.org/packages/SlowCheetah/" target="_blank"&gt;SlowCheetah&lt;/a&gt; integration. Instead of seeing a folder structure like this in the project…&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;~/Config      &lt;ul&gt;       &lt;li&gt;MyConfig.config &lt;/li&gt;        &lt;li&gt;MyConfig.Debug.config &lt;/li&gt;        &lt;li&gt;MyConfig.Release.config &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I wanted to see the file dependencies set up like you usually get with Web.config:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;~/Config      &lt;ul&gt;       &lt;li&gt;MyConfig.config          &lt;ul&gt;           &lt;li&gt;MyConfig.Debug.config &lt;/li&gt;            &lt;li&gt;MyConfig.Release.config &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That's not really a straightforward thing to do, as it turns out.&lt;/p&gt;  &lt;p&gt;Luckily, &lt;a href="http://docs.nuget.org/docs/creating-packages/creating-and-publishing-a-package" target="_blank"&gt;NuGet provides your package the ability to have a PowerShell script run at install time&lt;/a&gt;, and part of what it passes you is a reference to &lt;a href="http://msdn.microsoft.com/en-us/library/51h9a6ew(v=vs.110).aspx" target="_blank"&gt;the EnvDTE project&lt;/a&gt; into which the package is being installed.&lt;/p&gt;  &lt;p&gt;EnvDTE is the way you automate Visual Studio for things like custom tools and add-ins. &lt;a href="http://www.paraesthesia.com/archive/2004/06/25/solvent---power-toys-for-visual-studio-.net.aspx" target="_blank"&gt;I've messed around with EnvDTE before&lt;/a&gt; (though lately &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/" target="_blank"&gt;I prefer using CodeRush for my automation tasks&lt;/a&gt;) so this wasn't too hard to get back into. Here's the script for Install.ps1:&lt;/p&gt;  &lt;pre&gt;param($installPath, $toolsPath, $package, $project)
# Sets the configuration files to have dependent transforms (.Debug/.Release).
# Selections of items in the project are done with Where-Object rather than direct
# access into the ProjectItems collection because if the object is moved or doesn't
# exist then Where-Object will give us a null response rather than the error that
# DTE will give us.

$configFolder = $project.ProjectItems | Where-Object { $_.Properties.Item("Filename").Value -eq "Config" -and  $_.ProjectItems.Count -gt 0 }
if($configFolder -eq $null)
{
  # Upgrade scenario - user has moved/removed the Config folder
  # or has moved/removed the configuration files out of the folder.
  return
}

$baseConfig = $configFolder.ProjectItems | Where-Object { $_.Properties.Item("Filename").Value -eq "MyConfig.config" -and $_.ProjectItems.Count -eq 0 }
if($baseConfig -eq $null)
{
  # Upgrade scenario - user has moved/removed the MyConfig.config file
  # or it already has the dependent items set.
  return
}

# Config file exists, so update the properties.
$baseConfig.Properties.Item("SubType").Value = "Designer"

$debugConfig = $configFolder.ProjectItems | Where-Object { $_.Properties.Item("Filename").Value -eq "MyConfig.Debug.config" }
if($debugConfig -eq $null)
{
  # Upgrade scenario - user has moved/removed the MyConfig.Debug.config file
  # or it's already set as a dependent item. (Dependent items show up as children
  # of the file on which they depend, not as a child of the folder.)
  return
}

# Handle the update for MyConfig.Debug.config - set it as BuildAction = None
# and move it to be a dependency of MyConfig.config.
$debugConfig.Properties.Item("ItemType").Value = "None"
$baseConfig.ProjectItems.AddFromFile($debugConfig.Properties.Item("FullPath").Value)

$releaseConfig = $configFolder.ProjectItems | Where-Object { $_.Properties.Item("Filename").Value -eq "MyConfig.Release.config" }
if($releaseConfig -eq $null)
{
  # Upgrade scenario - user has moved/removed the MyConfig.Release.config file
  # or it's already set as a dependent item. (Dependent items show up as children
  # of the file on which they depend, not as a child of the folder.)
  return
}

# Handle the update for MyConfig.Release.config - set it as BuildAction = None
# and move it to be a dependency of MyConfig.config.
$releaseConfig.Properties.Item("ItemType").Value = "None"
$baseConfig.ProjectItems.AddFromFile($releaseConfig.Properties.Item("FullPath").Value)&lt;/pre&gt;

&lt;p&gt;What this does is switch this .csproj snippet…&lt;/p&gt;

&lt;pre&gt;&amp;lt;ItemGroup&amp;gt;
  &amp;lt;Content Include="MyConfig.config" /&amp;gt;
  &amp;lt;Content Include="MyConfig.Debug.config" /&amp;gt;
  &amp;lt;Content Include="MyConfig.Release.config" /&amp;gt;
&amp;lt;ItemGroup&amp;gt;&lt;/pre&gt;

&lt;p&gt;Into this:&lt;/p&gt;

&lt;pre&gt;&amp;lt;ItemGroup&amp;gt;
  &amp;lt;Content Include="MyConfig.config"&amp;gt;
    &amp;lt;SubType&amp;gt;Designer&amp;lt;/SubType&amp;gt;
  &amp;lt;/Content&amp;gt;
  &amp;lt;None Include="MyConfig.Debug.config"&amp;gt;
    &amp;lt;DependentUpon&amp;gt;MyConfig.config&amp;lt;/DependentUpon&amp;gt;
  &amp;lt;/None&amp;gt;
  &amp;lt;None Include="MyConfig.Release.config"&amp;gt;
    &amp;lt;DependentUpon&amp;gt;MyConfig.config&amp;lt;/DependentUpon&amp;gt;
  &amp;lt;/None&amp;gt;
&amp;lt;ItemGroup&amp;gt;&lt;/pre&gt;

&lt;p&gt;What I've not yet figured out is how to get a new custom element &lt;code&gt;&amp;lt;TransformOnBuild&amp;gt;true&amp;lt;/TransformOnBuild&amp;gt;&lt;/code&gt; to show up on the MyConfig.config element. &lt;a href="http://msdn.microsoft.com/en-us/library/vstudio/bb491814.aspx" target="_blank"&gt;From this article on MSDN&lt;/a&gt;, it appears there's a much more involved bit of work to do and I'm not sure that I have access to all the requisite DTE objects from inside the script.&lt;/p&gt;&lt;img src="http://www.paraesthesia.com/aggbug/1818.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=DL-m_JqefzY:CooEliV0LUg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=DL-m_JqefzY:CooEliV0LUg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=DL-m_JqefzY:CooEliV0LUg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=DL-m_JqefzY:CooEliV0LUg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=DL-m_JqefzY:CooEliV0LUg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=DL-m_JqefzY:CooEliV0LUg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=DL-m_JqefzY:CooEliV0LUg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=DL-m_JqefzY:CooEliV0LUg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=DL-m_JqefzY:CooEliV0LUg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Paraesthesia/~4/DL-m_JqefzY" height="1" width="1"/&gt;</description>
            <dc:creator>Travis Illig</dc:creator>
            <guid isPermaLink="false">http://www.paraesthesia.com/archive/2013/05/15/setting-dependentupon-file-properties-on-nuget-package-install.aspx</guid>
            <pubDate>Wed, 15 May 2013 16:12:19 GMT</pubDate>
            <comments>http://www.paraesthesia.com/archive/2013/05/15/setting-dependentupon-file-properties-on-nuget-package-install.aspx#feedback</comments>
            <wfw:commentRss>http://www.paraesthesia.com/comments/commentRss/1818.aspx</wfw:commentRss>
        <feedburner:origLink>http://www.paraesthesia.com/archive/2013/05/15/setting-dependentupon-file-properties-on-nuget-package-install.aspx</feedburner:origLink></item>
        <item>
            <title>Scared of Bears</title>
            <category>General Ramblings</category>
            <link>http://feedproxy.google.com/~r/Paraesthesia/~3/lGTTkMNmszc/scared-of-bears.aspx</link>
            <description>&lt;p&gt;We've had a recent issue where Phoenix won't do something because she claims she's "scared".&lt;/p&gt;  &lt;p&gt;"Phoenix, can you come over here?"&lt;/p&gt;  &lt;p&gt;"No," she says. "I scared."&lt;/p&gt;  &lt;p&gt;"What are you scared of?" As if we didn't already know.&lt;/p&gt;  &lt;p&gt;"Bears. Bears eat my shoes."&lt;/p&gt;  &lt;p&gt;That's right, she's scared of bears eating her shoes. Or her coat. Or my car. Pretty much anything out there is something waiting for a bear to eat it. At night, we have this somewhat covered.&lt;/p&gt;  &lt;p&gt;"The bear can't get you, Phoenix, because you have your unicorn to protect you. Unicorns stop bears." We'll hand her this little stuffed unicorn and all is well.&lt;/p&gt;  &lt;p&gt;"My un-corn." Long "u" is a hard sound, I guess, so it's not "unicorn," it's "un-corn." Whatever.&lt;/p&gt;  &lt;p&gt;This morning in the car, though, I didn't have the unicorn and the bear talk started. I tried to think up something new.&lt;/p&gt;  &lt;p&gt;"Daddy, I scared."&lt;/p&gt;  &lt;p&gt;Sigh. No unicorn. Well, let's just get down to it. "Are you scared of bears?"&lt;/p&gt;  &lt;p&gt;"Yes. Bears eat my shoes."&lt;/p&gt;  &lt;p&gt;"I know. But you like dragons, right?"&lt;/p&gt;  &lt;p&gt;"I not dragon, I princen." Hard "s" is also difficult, so "princess" becomes "princen."&lt;/p&gt;  &lt;p&gt;"Yes, you're a princess… are you princess of the dragons?" I think you &lt;em&gt;Game of Thrones&lt;/em&gt; folks see where I'm going with this.&lt;/p&gt;  &lt;p&gt;"I princen of dragons!"&lt;/p&gt;  &lt;p&gt;"That's right, you're the Khaleesi."&lt;/p&gt;  &lt;p&gt;"I kee-see!"&lt;/p&gt;  &lt;p&gt;"Now, tell your dragons to stop the bears. Dragons can stop bears."&lt;/p&gt;  &lt;p&gt;"No, I not tell dragons."&lt;/p&gt;  &lt;p&gt;Dammit. "Why not?"&lt;/p&gt;  &lt;p&gt;"Dragons scared of bears."&lt;/p&gt;  &lt;p&gt;Are you freaking kidding me? "Are you sure?" Then, out of nowhere…&lt;/p&gt;  &lt;p&gt;"PA-KOW! PA-KOW! I shoot bear!"&lt;/p&gt;  &lt;p&gt;O_o&lt;/p&gt;  &lt;p&gt;Wait, what? "Phoe, you &lt;em&gt;shot&lt;/em&gt; the bear?"&lt;/p&gt;  &lt;p&gt;"PA-KOW! I shoot bear!"&lt;/p&gt;  &lt;p&gt;Um. Well, uh… I'm not really sure where she picked that one up, but… I guess… bear problem solved, right?&lt;/p&gt;&lt;img src="http://www.paraesthesia.com/aggbug/1817.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=lGTTkMNmszc:dNEuT3iahWc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=lGTTkMNmszc:dNEuT3iahWc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=lGTTkMNmszc:dNEuT3iahWc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=lGTTkMNmszc:dNEuT3iahWc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=lGTTkMNmszc:dNEuT3iahWc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=lGTTkMNmszc:dNEuT3iahWc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=lGTTkMNmszc:dNEuT3iahWc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=lGTTkMNmszc:dNEuT3iahWc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=lGTTkMNmszc:dNEuT3iahWc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Paraesthesia/~4/lGTTkMNmszc" height="1" width="1"/&gt;</description>
            <dc:creator>Travis Illig</dc:creator>
            <guid isPermaLink="false">http://www.paraesthesia.com/archive/2013/04/25/scared-of-bears.aspx</guid>
            <pubDate>Thu, 25 Apr 2013 15:08:18 GMT</pubDate>
            <comments>http://www.paraesthesia.com/archive/2013/04/25/scared-of-bears.aspx#feedback</comments>
            <wfw:commentRss>http://www.paraesthesia.com/comments/commentRss/1817.aspx</wfw:commentRss>
        <feedburner:origLink>http://www.paraesthesia.com/archive/2013/04/25/scared-of-bears.aspx</feedburner:origLink></item>
        <item>
            <title>FluentValidation and MVC - From Server to Client</title>
            <category>.NET</category>
            <category>Web Development</category>
            <category>GeekSpeak</category>
            <link>http://feedproxy.google.com/~r/Paraesthesia/~3/bZ-YlG_3oLo/fluentvalidation-and-mvc-from-server-to-client.aspx</link>
            <description>&lt;p&gt;We do a lot of interesting stuff with &lt;a href="http://fluentvalidation.codeplex.com/" target="_blank"&gt;FluentValidation&lt;/a&gt; at work and more than a few times I've had to give the whiteboard presentation of how a server-side FluentValidation validator makes it to &lt;a href="http://docs.jquery.com/Plugins/Validation" target="_blank"&gt;jQuery validation rules&lt;/a&gt; on the client and back. I figured it was probably time to just write it up so I can refer folks as needed.&lt;/p&gt;  &lt;p&gt;Let's start out with a simple model we want to validate. We'll carry these examples with us in the walkthrough so you have something concrete to tie back to.&lt;/p&gt;  &lt;pre&gt;public class MyModel
{
  public string Name { get; set; }
  public int Age { get; set; }
}&lt;/pre&gt;

&lt;p&gt;On the server, we'd validate that model using FluentValidation by implementing &lt;code&gt;FluentValidation.AbstractValidator&amp;lt;T&amp;gt;&lt;/code&gt; like this:&lt;/p&gt;

&lt;pre&gt;public class MyModelValidator : AbstractValidator&amp;lt;MyModel&amp;gt;
{
    public MyModelValidator()
    {
      RuleFor(m =&amp;gt; m.Name)
        .NotEmpty()
        .WithMessage("Please provide a name.");

      RuleFor(m =&amp;gt; m.Age)
        .GreaterThan(21)
        .WithMessage("You must be over 21 to access this site.");
    }
}&lt;/pre&gt;

&lt;p&gt;First let's look at the way rules are set up in FluentValidation. You'll see that each call to &lt;code&gt;RuleFor&lt;/code&gt; points to a property we want to validate. Calling &lt;code&gt;RuleFor&lt;/code&gt; sort of starts a "stack" of validators that are associated with that property. Each method that adds a validation (&lt;code&gt;NotEmpty&lt;/code&gt;, &lt;code&gt;GreaterThan&lt;/code&gt;) adds that validator to the "stack" and then sets it as "active" so other extensions that modify behavior (&lt;code&gt;WithMessage&lt;/code&gt;) will know which validator they're modifying.&lt;/p&gt;

&lt;p&gt;A more complex setup might look like this:&lt;/p&gt;

&lt;pre&gt;RuleFor(m =&amp;gt; m.Name)                        // Start a new validation "rule" with a set of validators attached
  .NotEmpty()                               // Add a NotEmptyValidator to the stack and make it "active"
  .WithMessage("Please provide a name.")    // Set the message for the NotEmptyValidator
  .Matches("[a-zA-Z]+")                     // Add a RegularExpressionValidator to the stack and make it "active"
  .WithMessage("Please use only letters."); // Set the message for the RegularExpressionValidator&lt;/pre&gt;

&lt;p&gt;In a server-side only scenario, when you validate an object each "rule" gets iterated through and each validator associated with that "rule" gets executed. More or less. There's a bit of complexity to it, but that's a good way to explain it without getting into the weeds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ASP.NET MVC ships with an abstraction around model validation that &lt;/strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.modelvalidatorprovider.aspx" target="_blank"&gt;&lt;strong&gt;starts with a &lt;code&gt;ModelValidatorProvider&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt; Out of the box, MVC has support for DataAnnotations attributes. (&lt;a href="http://rachelappel.com/asp-net-mvc/how-data-annotations-for-asp-net-mvc-validation-work/" target="_blank"&gt;Rachel Appel has a great walkthrough of how that works&lt;/a&gt;.) From the name, you can guess that &lt;strong&gt;what this does is &lt;em&gt;provide validators for your models&lt;/em&gt;.&lt;/strong&gt; When MVC wants to validate your model (or determine how it's validated), it asks the set of registered &lt;code&gt;ModelValidatorProvider &lt;/code&gt;objects and they return the validators. It's dumb when I say it out loud, but the class names start getting really long and a little confusing, so I just wanted to bring this up now: if you start getting confused, really &lt;em&gt;stop to read the name of the class you're confused about&lt;/em&gt;. It'll help, trust me, because they all start sounding the same after a while.&lt;/p&gt;

&lt;p&gt;FluentValidation has an associated FluentValidation.Mvc library that has the MVC adapter components. In there is a &lt;code&gt;FluentValidationModelValidatorProvider&lt;/code&gt;. To get this hooked in, you need to register that &lt;code&gt;FluentValidationModelValidatorProvider &lt;/code&gt;with MVC at application startup. The easiest way to do this is by calling &lt;code&gt;FluentValidationModelValidatorProvider.Configure()&lt;/code&gt;, which automatically adds the provider to the list of available providers and also lets you do some additional configuration as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Things you can do in &lt;code&gt;FluentValidationModelValidatorProvider.Configure&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Specify the validator factory to use on the server to retrieve FluentValidation validators corresponding to models. &lt;/li&gt;

  &lt;li&gt;Add mappings for custom validators that map between the server-side FluentValidation validator and the MVC client-side validation logic. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Right now we'll talk about the validator factory piece&lt;/strong&gt;. I'll get to the custom validator mappings later.&lt;/p&gt;

&lt;p&gt;As mentioned, when you run &lt;code&gt;FluentValidationModelValidatorProvider.Configure()&lt;/code&gt;, you can tell it which &lt;code&gt;FluentValidation.IValidatorFactory &lt;/code&gt;to use for mapping server-side validators (like the &lt;code&gt;MyModelValidator&lt;/code&gt;) to models (like &lt;code&gt;MyModel&lt;/code&gt;). Out of the box, FluentValidation ships with the &lt;code&gt;FluentValidation.Attributes.AttributedValidatorFactory&lt;/code&gt;. This factory type lets you attach validators to your models with attributes, like this:&lt;/p&gt;

&lt;pre&gt;[Validator(typeof(MyModelValidator))]
public class MyModel
{
  // ...
}&lt;/pre&gt;

&lt;p&gt;That's one way to go, but I find that to be somewhat inflexible. I also don't like my code too closely tied together like that, so instead, in MVC, I like to use the &lt;code&gt;DependencyResolver &lt;/code&gt;to get my model-validator mappings. FluentValidation doesn't ship with a factory that uses &lt;code&gt;DependencyResolver&lt;/code&gt;, but it's pretty easy to implement:&lt;/p&gt;

&lt;pre&gt;public class DependencyResolverModelValidatorFactory : IValidatorFactory
{
  public IValidator GetValidator(Type type)
  {
    if (type == null)
    {
      throw new ArgumentNullException("type");
    }
    return DependencyResolver.Current.GetService(typeof(IValidator&amp;lt;&amp;gt;).MakeGenericType(type)) as IValidator;
  }

  public IValidator&amp;lt;T&amp;gt; GetValidator&amp;lt;T&amp;gt;()
  {
    return DependencyResolver.Current.GetService&amp;lt;IValidator&amp;lt;T&amp;gt;&amp;gt;();
  }
}&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Using that validator factory, you need to register your validators with your chosen &lt;/strong&gt;&lt;code&gt;&lt;strong&gt;DependencyResolver&lt;/strong&gt; &lt;/code&gt;so that they're exposed as &lt;code&gt;IValidator&amp;lt;T&amp;gt;&lt;/code&gt; (like &lt;code&gt;IValidator&amp;lt;MyModel&amp;gt;&lt;/code&gt;). Luckily &lt;code&gt;AbstractValidator&amp;lt;T&amp;gt; &lt;/code&gt;implements that interface, so you're set. In &lt;a href="https://autofac.googlecode.com" target="_blank"&gt;Autofac&lt;/a&gt; (my IoC container of choice) the validator registration during container setup would look like...&lt;/p&gt;

&lt;pre&gt;containerBuilder.RegisterType&amp;lt;MyModelValidator&amp;gt;().As&amp;lt;IValidator&amp;lt;MyModel&amp;gt;&amp;gt;();&lt;/pre&gt;

&lt;p&gt;To register the model validator factory with FluentValidation, we'd do that during &lt;code&gt;FluentValidationModelValidatorProvider.Configure()&lt;/code&gt; at application startup, like this:&lt;/p&gt;

&lt;pre&gt;FluentValidationModelValidatorProvider.Configure(
  provider =&amp;gt;
  {
    provider.ValidatorFactory = new DependencyResolverModelValidatorFactory();
  });&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Let's checkpoint.&lt;/strong&gt; Up to now we have:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;A custom validator&lt;/strong&gt; for our model. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;A validator factory&lt;/strong&gt; for FluentValidation that will tie our validator to our model using dependency resolution. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;FluentValidation configured in MVC&lt;/strong&gt; to be a source of model validations. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next let's talk about &lt;strong&gt;how the FluentValidation validators get their results into the MVC &lt;code&gt;ModelState&lt;/code&gt;&lt;/strong&gt; for server-side validation.&lt;/p&gt;

&lt;p&gt;ASP.NET MVC has a class called &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.modelvalidator.aspx" target="_blank"&gt;ModelValidator&lt;/a&gt;&lt;/code&gt; that is used to abstract away the concept of model validation. It's responsible for generating the validation errors that end up in &lt;code&gt;ModelState&lt;/code&gt; as well as the set of client validation rules that define how the browser-side behavior gets wired up. The ModelValidator class has two methods, each of which corresponds to one of these responsibilities.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Validate&lt;/strong&gt;: Executes server-side validation of the model and returns the list of results. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;GetClientValidationRules&lt;/strong&gt;: Gets metadata in the form of &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.modelclientvalidationrule.aspx" target="_blank"&gt;ModelClientValidationRule&lt;/a&gt;&lt;/code&gt; objects to send to the client so script can do client-side validation. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For DataAnnotations, there are implementations of &lt;code&gt;ModelValidator &lt;/code&gt;corresponding to each attribute. For FluentValidation, there are &lt;code&gt;ModelValidator &lt;/code&gt;implementations that correspond to each server-side validation type. For example, looking at our &lt;code&gt;MyModel.Name &lt;/code&gt;property, we have a &lt;code&gt;NotEmptyValidator &lt;/code&gt;attached to it. That &lt;code&gt;NotEmptyValidator &lt;/code&gt;maps to a &lt;code&gt;FluentValidation.Mvc.RequiredFluentValidationPropertyValidator&lt;/code&gt;. These mappings are maintained by the &lt;code&gt;FluentValidationModelValidatorProvider&lt;/code&gt;. (Remember I said you could add custom mappings during the call to Configure? This is what I was talking about.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When MVC needs the set of &lt;code&gt;ModelValidator &lt;/code&gt;implementations associated with a model, the basic process is this:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code&gt;ModelValidatorProviders.Providers.GetValidators&lt;/code&gt; method is called. This iterates through the registered providers to get all the validators available. Eventually the &lt;code&gt;FluentValidationModelValidatorProvider &lt;/code&gt;is queried. &lt;/li&gt;

  &lt;li&gt;The &lt;code&gt;FluentValidationModelValidatorProvider &lt;/code&gt;uses the registered &lt;code&gt;IValidatorFactory &lt;/code&gt;(&lt;code&gt;DependencyResolverModelValidatorFactory&lt;/code&gt;) to get the FluentValidation validator (&lt;code&gt;MyModelValidator&lt;/code&gt;) associated with the model (&lt;code&gt;MyModel&lt;/code&gt;). &lt;/li&gt;

  &lt;li&gt;The &lt;code&gt;FluentValidationModelValidatorProvider &lt;/code&gt;then looks at the rules associated with the property being validated (&lt;code&gt;MyModel.Name&lt;/code&gt;) and converts each validator in the rule (&lt;code&gt;NotEmptyValidator&lt;/code&gt;) into its mapped MVC &lt;code&gt;ModelValidator &lt;/code&gt;type (&lt;code&gt;RequiredFluentValidationPropertyValidator&lt;/code&gt;). &lt;/li&gt;

  &lt;li&gt;The list of mapped &lt;code&gt;ModelValidator &lt;/code&gt;instances is returned to MVC for execution. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Here's where it starts coming together.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you do an MVC HtmlHelper call to render a data entry field for a model property, it looks something like this:&lt;/p&gt;

&lt;pre&gt;@Html.TextBoxFor(m =&amp;gt; m.Name)&lt;/pre&gt;

&lt;p&gt;Internally, during the textbox generation, a bit more happens under the covers:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The input field HTML generation process calls &lt;code&gt;ModelValidatorProviders.Providers.GetValidators &lt;/code&gt;for the field. (This is the process mentioned earlier.) &lt;/li&gt;

  &lt;li&gt;The &lt;code&gt;ModelValidator&lt;/code&gt;(s) returned each have &lt;code&gt;GetClientValidationRules&lt;/code&gt; called to get the set of &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.modelclientvalidationrule.aspx" target="_blank"&gt;ModelClientValidationRule&lt;/a&gt;&lt;/code&gt; data defining the client-side validation info. &lt;/li&gt;

  &lt;li&gt;The &lt;code&gt;ModelClientValidationRule &lt;/code&gt;objects get converted to &lt;code&gt;data-val-&lt;/code&gt; attributes that will be attached to the input field. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using our example, if we did that &lt;code&gt;Html.TextBoxFor(m =&amp;gt; m.Name)&lt;/code&gt; call…&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code&gt;FluentValidationModelValidatorProvider &lt;/code&gt;would, through the process mentioned earlier, yield a &lt;code&gt;RequiredFluentValidationPropertyValidator &lt;/code&gt;corresponding to the &lt;code&gt;NotEmptyValidator &lt;/code&gt;we're using on the &lt;code&gt;Name &lt;/code&gt;field. &lt;/li&gt;

  &lt;li&gt;That &lt;code&gt;RequiredFluentValidationPropertyValidator &lt;/code&gt;would have &lt;code&gt;GetClientValidationRules &lt;/code&gt;called to get the client-side validation information. I happen to know that the &lt;code&gt;RequiredFluentValidationPropertyValidator &lt;/code&gt;returns a &lt;code&gt;ModelValidationRequiredRule&lt;/code&gt;. &lt;/li&gt;

  &lt;li&gt;Each of the &lt;code&gt;ModelClientValidationRule &lt;/code&gt;objects (in this case, just the &lt;code&gt;ModelValidationRequiredRule&lt;/code&gt;) would be converted to &lt;code&gt;data-val-&lt;/code&gt; attributes on the textbox. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's in a &lt;code&gt;ModelClientValidationRule &lt;/code&gt;and how does it translate to attributes?&lt;/p&gt;

&lt;p&gt;Basically &lt;strong&gt;each &lt;code&gt;ModelClientValidationRule &lt;/code&gt;corresponds to a jQuery validation type&lt;/strong&gt;. The &lt;code&gt;ModelValidationRequiredRule &lt;/code&gt;is basically just a pre-populated &lt;code&gt;ModelClientValidationRule &lt;/code&gt;derivative that looks like this:&lt;/p&gt;

&lt;pre&gt;new ModelClientValidationRule
{
  ValidationType = "required",
  ErrorMessage = "Please provide a name."
}&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;ValidationType &lt;/code&gt;corresponds to &lt;a href="http://docs.jquery.com/Plugins/Validation#List_of_built-in_Validation_methods" target="_blank"&gt;the name of a jQuery validation type&lt;/a&gt; and the error message is the one we specified way back when we defined our FluentValidation validator.&lt;/p&gt;

&lt;p&gt;When that gets converted into data-val- attributes, it ends up looking like this:&lt;/p&gt;

&lt;pre&gt;&amp;lt;input type="text" ... data-val-required="Please provide a name." /&amp;gt;&lt;/pre&gt;

&lt;p&gt;That's how the validation information gets from the server to the client. Once it's there, it's time for script to pick it up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MVC uses jQuery validation&lt;/strong&gt; to execute the client-side validation. It takes advantage of a library &lt;strong&gt;jQuery Unobtrusive Validation&lt;/strong&gt; which is used to parse the &lt;code&gt;data-val-&lt;/code&gt; attributes into client-side logic. The attributes fairly well correspond one-to-one with existing jQuery validation rules. For example, &lt;code&gt;data-val-required&lt;/code&gt; corresponds to &lt;a href="http://docs.jquery.com/Plugins/Validation/Methods/required" target="_blank"&gt;the required() validation method&lt;/a&gt;. That jQuery Unobtrusive Validation library reads the attributes and maps them (and their values) into jQuery validation actions that are attached to the form. Standard jQuery validation takes it from there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The whole process for validating a submitted form is&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code&gt;Html.TextBoxFor &lt;/code&gt;call gets the set of validators for the field and attaches the &lt;code&gt;data-val-&lt;/code&gt; attributes to it using the process described earlier. &lt;/li&gt;

  &lt;li&gt;jQuery Unobtrusive Validation parses the attributes on the client and sets up the client-side validation. &lt;/li&gt;

  &lt;li&gt;When the user submits the form, jQuery validation executes. Assuming it passes, the form gets submitted to the server. &lt;/li&gt;

  &lt;li&gt;During model binding, the MVC &lt;code&gt;DefaultModelBinder &lt;/code&gt;gets the list of &lt;code&gt;ModelValidator &lt;/code&gt;instances for the model using the process described earlier. &lt;/li&gt;

  &lt;li&gt;Each &lt;code&gt;ModelValidator &lt;/code&gt;gets its &lt;code&gt;Validate &lt;/code&gt;method called. Any failures will get added to the &lt;code&gt;ModelState &lt;/code&gt;by the &lt;code&gt;DefaultModelBinder&lt;/code&gt;. In our case, the &lt;code&gt;RequiredFluentValidationPropertyValidator &lt;/code&gt;will pass through to our originally configured &lt;code&gt;NotEmptyValidator &lt;/code&gt;on the server side and the results of the &lt;code&gt;NotEmptyValidator &lt;/code&gt;will be translated into &lt;code&gt;ModelValidationResult &lt;/code&gt;objects for use by the &lt;code&gt;DefaultModelBinder&lt;/code&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Whew! That's a lot of moving pieces.&lt;/strong&gt; But that should explain how it comes together so you at least know what you're looking at.&lt;/p&gt;

&lt;p&gt;When you want to add a custom server-side validator, you have to hook into that process. Knowing the steps outlined above, you can see you have a few things to do (and a few places where things can potentially break down).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The basic steps for adding a new custom FluentValidation validator in MVC are&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Create your server-side validator.&lt;/strong&gt; This means implementing &lt;code&gt;FluentValidation.Validators.IPropertyValidator&lt;/code&gt;. It's what gets used on the server for validation but doesn't do anything on the client. I'd look at existing validators to get ideas on how to do this, since it's a little different based on whether, say, you're comparing two properties on the same object or comparing a property with a fixed value. I'd recommend starting by looking at a validator that does something similar to what you want to do. The beauty of open source. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Add an extension method that allows your new validator type&lt;/strong&gt; to participate in the fluent grammar. The standard ones are in &lt;code&gt;FluentValidation.DefaultValidatorExtensions&lt;/code&gt;. This is how you get nice syntax like &lt;code&gt;RuleFor(m =&amp;gt; m.Name).MyCustomValidator();&lt;/code&gt; for your custom validator. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Create a &lt;code&gt;FluentValidation.Mvc.FluentValidationPropertyValidator &lt;/code&gt;corresponding to your server-side validator.&lt;/strong&gt; This will be responsible for creating the appropriate &lt;code&gt;ModelClientValidationRule &lt;/code&gt;objects to tie your server-side validator to the client and for executing the corresponding server-side logic. (Really the work is in the client-side part of things. The base &lt;code&gt;FluentValidationPropertyValidator &lt;/code&gt;already passes-through logic to your custom server-side validator so you don't have to really &lt;em&gt;do anything&lt;/em&gt; to get that to happen.) &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Add a mapping between your server-side validator and your &lt;code&gt;FluentValidationPropertyValidator&lt;/code&gt;.&lt;/strong&gt; This takes place in &lt;code&gt;FluentValidationModelValidatorProvider.Configure&lt;/code&gt;. Let's talk about that. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Remember earlier I said we'd talk about adding custom validator mappings to the &lt;code&gt;&lt;strong&gt;FluentValidationModelValidatorProvider&lt;/strong&gt; &lt;/code&gt;&lt;/strong&gt;during configuration time? You need to do that if you write your own custom validator. When you want to map a server-side validator to a client-side validator, it looks like this:&lt;/p&gt;

&lt;pre&gt;FluentValidationModelValidatorProvider.Configure(
  provider =&amp;gt;
  {
    provider.ValidatorFactory = new DependencyResolverModelValidatorFactory();
    provider.Add(
      typeof(MyCustomValidator),
      (metadata, context, rule, validator) =&amp;gt; new MyCustomFluentValidationPropertyValidator(metadata, context, rule, validator));
  });&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;There are mappings already for the built-in validators.&lt;/strong&gt; You just have to add your custom ones. Unfortunately, the actual list of mappings itself isn't documented anywhere I can find, so &lt;a href="http://fluentvalidation.codeplex.com/SourceControl/changeset/view/f8bfa66ff2a28f731f126fedf22dfaa35438ba7f#src/FluentValidation.Mvc3/FluentValidationModelValidatorProvider.cs" target="_blank"&gt;you'll need to look at the static constructor on &lt;code&gt;FluentValidationModelValidatorProvider&lt;/code&gt;&lt;/a&gt; to see what maps to what by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I won't walk through the full creation of an end-to-end custom validator here.&lt;/strong&gt; That's probably another article since this is already way, way too long without enough pictures to break up the monotony. Instead, I'll just mention a couple of gotchas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GOTCHA: DERIVING FROM OUT-OF-THE-BOX VALIDATORS 
    &lt;br /&gt;&lt;/strong&gt;Say you have a custom email validator. You decide you want to shortcut a few things by just deriving from the original email validator and overriding a couple of things. Sounds fine, right?&lt;/p&gt;

&lt;pre&gt;public class MyCustomEmailValidator : EmailValidator&lt;/pre&gt;

&lt;p&gt;Or maybe you don't do that, but you do decide to implement the standard FluentValidation email validator interface:&lt;/p&gt;

&lt;pre&gt;public class MyCustomEmailValidator : PropertyValidator, IEmailValidator&lt;/pre&gt;

&lt;p&gt;The gotcha here is that server-side-to-client-side mapping that I showed you earlier. FluentValidation maps by type and already ships with mappings for the out-of-the-box validators. If you implement your custom validator like this, chances are you're going to end up with the default client-side logic rather than your custom one. The default was registered first, right? It'll never get to your override… and there's not really a way to remove mappings.&lt;/p&gt;

&lt;p&gt;You also&lt;strong&gt; don't want to override the mapping&lt;/strong&gt; like this:&lt;/p&gt;

&lt;pre&gt;provider.Add(
  typeof(IEmailValidator),
  (metadata, context, rule, validator) =&amp;gt; new MyCustomFluentValidationPropertyValidator(metadata, context, rule, validator));&lt;/pre&gt;

&lt;p&gt;You don't want to do that because then when you use the out-of-the-box email validator, it'll end up with your custom logic.&lt;/p&gt;

&lt;p&gt;This is really painful to debug. Sometimes this is actually what you want - reuse of client (or server) logic but not both… but generally, you want a unique custom validator from end to end.&lt;/p&gt;

&lt;p&gt;Recommendation: &lt;strong&gt;Don't implement the standard interfaces unless you plan on &lt;em&gt;replacing the standard behavior across the board&lt;/em&gt;&lt;/strong&gt; and not using the out-of-the-box validator of that type. (That is, if you want to totally replace everything about client and server validation for &lt;code&gt;IEmailValidator&lt;/code&gt;, then implement &lt;code&gt;IEmailValidator &lt;/code&gt;on your server-side validator and don't use the standard email validator anymore.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GOTCHA: CUSTOM VALIDATION LAMBDAS ONLY RUN ON THE SERVER&lt;/strong&gt; 

  &lt;br /&gt;Say you don't want to implement a whole custom validator and would rather use the FluentValidation lambda syntax like this:&lt;/p&gt;

&lt;pre&gt;RuleFor(m =&amp;gt; m.Age).Must(val =&amp;gt; val - 2 &amp;gt; 6);&lt;/pre&gt;

&lt;p&gt;That lambda will only run on the server. Maybe that's OK for a quick one-off, but if you want corresponding client-side validation you actually need to implement the end-to-end solution. There's no automated functionality for translating the lambdas into script, nor is there an automatic facility for converting this into an AJAX remote validation call. (But that's a pretty neat idea.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GOTCHA: MVC CLIENT-SIDE VALIDATION ADAPTERS OVERLAP TYPES&lt;/strong&gt; 

  &lt;br /&gt;If you dive deep enough, you'll notice that certain server-side FluentValidation validators boil down to the same &lt;code&gt;ModelClientValidationRule &lt;/code&gt;values when it's time to emit the &lt;code&gt;data-val-&lt;/code&gt; attributes. For example, the FluentValidation &lt;code&gt;GreaterThanValidator &lt;/code&gt;and &lt;code&gt;LessThaValidator &lt;/code&gt;both end up with &lt;code&gt;ModelClientValidationRule &lt;/code&gt;values that say the validation type is "range" (not "min" or "max" as you might expect). What that means is that on the server side, this looks sweet and works:&lt;/p&gt;

&lt;pre&gt;RuleFor(m =&amp;gt; m.Age).GreaterThan(5).LessThan(10);&lt;/pre&gt;

&lt;p&gt;But when you try to render the corresponding textbox, you're going to get an exception telling you that you can't put "range" validation twice on the same field. Problem.&lt;/p&gt;

&lt;p&gt;What it means is that &lt;strong&gt;when you create custom validations, you have to be mindful of which jQuery rule you're going to associate it with on the client&lt;/strong&gt;. It also means you have to be creative, sometimes, about how you set up MVC validations on the server to make sure you don't have problems when it comes to adapting things to the client-side. Stuff that works on the server won't necessarily work in MVC.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://imageshack.us/a/img441/9756/fluentvalidationsequenc.png" target="_blank"&gt;&lt;strong&gt;For reference, here's a SUPER ABBREVIATED SEQUENCE DIAGRAM of how it comes together.&lt;/strong&gt;&lt;/a&gt; Again, there are several steps omitted here, but this should at least jog your memory and help you visualize all the stuff I mentioned above.&lt;/p&gt;&lt;img src="http://www.paraesthesia.com/aggbug/1816.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bZ-YlG_3oLo:_KagXl9-c94:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bZ-YlG_3oLo:_KagXl9-c94:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=bZ-YlG_3oLo:_KagXl9-c94:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bZ-YlG_3oLo:_KagXl9-c94:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bZ-YlG_3oLo:_KagXl9-c94:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=bZ-YlG_3oLo:_KagXl9-c94:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bZ-YlG_3oLo:_KagXl9-c94:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bZ-YlG_3oLo:_KagXl9-c94:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=bZ-YlG_3oLo:_KagXl9-c94:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Paraesthesia/~4/bZ-YlG_3oLo" height="1" width="1"/&gt;</description>
            <dc:creator>Travis Illig</dc:creator>
            <guid isPermaLink="false">http://www.paraesthesia.com/archive/2013/04/17/fluentvalidation-and-mvc-from-server-to-client.aspx</guid>
            <pubDate>Wed, 17 Apr 2013 20:20:57 GMT</pubDate>
            <comments>http://www.paraesthesia.com/archive/2013/04/17/fluentvalidation-and-mvc-from-server-to-client.aspx#feedback</comments>
            <wfw:commentRss>http://www.paraesthesia.com/comments/commentRss/1816.aspx</wfw:commentRss>
        <feedburner:origLink>http://www.paraesthesia.com/archive/2013/04/17/fluentvalidation-and-mvc-from-server-to-client.aspx</feedburner:origLink></item>
        <item>
            <title>Portable Class Library Answers</title>
            <category>.NET</category>
            <link>http://feedproxy.google.com/~r/Paraesthesia/~3/zax3PXbMBEc/portable-class-library-answers.aspx</link>
            <description>&lt;p&gt;Since we switched &lt;a href="https://autofac.googlecode.com" target="_blank"&gt;Autofac&lt;/a&gt; to be a &lt;a href="http://msdn.microsoft.com/en-us/library/gg597391.aspx" target="_blank"&gt;Portable Class Library&lt;/a&gt;, it's been nice not having to maintain different builds for different platforms. It's also nice to not have preprocessor directives littered through the code. Props to Microsoft for making it part of VS2012.&lt;/p&gt;  &lt;p&gt;The problem is… not very many people are familiar with Portable Class Libraries and what they do. Probably once a week (give or take) we'll get a defect filed on Autofac that it's targeting the wrong version of .NET or something along those lines.&lt;/p&gt;  &lt;p&gt;To that end, I figured I'd blog the answers to some of the common questions we see. I also tried to summarize it &lt;a href="https://code.google.com/p/autofac/wiki/FrequentlyAskedQuestions" target="_blank"&gt;on the FAQ&lt;/a&gt;, but a couple of spots with the info never hurt.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Why are old versions of .NET referenced?&lt;/strong&gt;       &lt;br /&gt;If you pop open Autofac in Reflector, dotPeek, or your favorite decompiler, you'll see that it looks like it references .NET 2.0.5.0.       &lt;br /&gt;&lt;img title="" alt="Autofac targeting System 2.0.5.0" src="http://imageshack.us/a/img90/3328/20130329retargetable.png" width="355" height="176" /&gt;       &lt;br /&gt;&lt;em&gt;This is not a problem&lt;/em&gt;. The important part is the "Retargetable=Yes" at the end of the reference. What that means is Autofac will use the version of the assembly in the hosting process. If it's .NET 4.5, that's what it'll use. If it's Windows Phone, it'll use that. You can &lt;a href="http://www.shujaat.net/2012/11/portable-retargetable-assemblies.html" target="_blank"&gt;read more about what "Retargetable" means here&lt;/a&gt;.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Why do I get an exception where a 2.0.5.0 assembly fails to load?&lt;/strong&gt;       &lt;br /&gt;If it's retargetable, why is it blowing up in .NET 4.5? I get an exception that looks like this:      &lt;pre&gt;Test 'MyNamespace.MyFixture.MyTest' failed: System.IO.FileLoadException : Could not load file or assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
    at Autofac.Builder.RegistrationData..ctor(Service defaultService)
    at Autofac.Builder.RegistrationBuilder`3..ctor(Service defaultService, TActivatorData activatorData, TRegistrationStyle style)
    at Autofac.RegistrationExtensions.RegisterInstance[T](ContainerBuilder builder, T instance)
    MyProject\MyFixture.cs(49,0): at MyNamespace.MyFixture.MyTest()&lt;/pre&gt;

    &lt;br /&gt;You're getting an exception because you haven't got the latest .NET updates. &lt;a href="http://www.paraesthesia.com/archive/2013/01/21/using-portable-class-libraries-update-net-framework.aspx" target="_blank"&gt;I have a blog article here that walks into that in more detail&lt;/a&gt;.

    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Why is FxCop failing with CA0060 assembly binding errors?&lt;/strong&gt;

    &lt;br /&gt;If you're building your project on Windows 8 or Windows Server 2012, chances are you haven't seen this error. However, on Windows 7 or Windows Server 2008R2, you might have seen FxCop fail with warning CA0060 because it can't find the 2.0.5.0 assemblies that Autofac appears to bind to. FxCop doesn't really "get" the whole "Retargetable" thing right now.

    &lt;br /&gt;

    &lt;br /&gt;First, make sure it's the 2.0.5.0 assemblies FxCop is complaining about. If it's something else, &lt;a href="http://www.paraesthesia.com/archive/2011/04/20/how-to-pass-parameters-to-fxcop-from-visual-studio-or.aspx" target="_blank"&gt;you may need to change the way you invoke FxCop so it ignores version&lt;/a&gt; or something like that.

    &lt;br /&gt;

    &lt;br /&gt;Assuming it really is the 2.0.5.0 assemblies, the best you can do is ignore them. It doesn't affect your analysis results since you're not analyzing Autofac anyway. &lt;a href="http://geekswithblogs.net/blachniet/archive/2011/07/12/avoiding-fxcop-warning-ca0060.aspx" target="_blank"&gt;This blog article shows you one way to ignore the error in your build&lt;/a&gt;. I, personally, ended up writing a little custom FxCop build task that handles both the FxCop version ignore thing and the CA0060 error. Either way, ignoring it is the easiest way to go. Actually installing various SDKs doesn't seem to help. (I tried.)

    &lt;br /&gt;&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;How come secannotate.exe isn't working for me?&lt;/strong&gt;

    &lt;br /&gt;Congratulations, you're one of the seven people out there who actually use secannotate. :)

    &lt;br /&gt;

    &lt;br /&gt;You need to pass the /d switch to secannotate and point to the Portable Class Library reference assemblies. &lt;a href="http://stackoverflow.com/questions/12360534/how-can-i-successfully-run-secannotate-exe-on-a-library-that-depends-on-a-portab" target="_blank"&gt;This StackOverflow question&lt;/a&gt; shows an example of the errors you might see in secannotate and the solution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Portable Class Libraries really do make targeting multiple platforms easy, but if you're new to them, hopefully this helps you understand why you're seeing some of the things you're seeing.&lt;/p&gt;&lt;img src="http://www.paraesthesia.com/aggbug/1815.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=zax3PXbMBEc:8rti7orYPOM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=zax3PXbMBEc:8rti7orYPOM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=zax3PXbMBEc:8rti7orYPOM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=zax3PXbMBEc:8rti7orYPOM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=zax3PXbMBEc:8rti7orYPOM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=zax3PXbMBEc:8rti7orYPOM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=zax3PXbMBEc:8rti7orYPOM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=zax3PXbMBEc:8rti7orYPOM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=zax3PXbMBEc:8rti7orYPOM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Paraesthesia/~4/zax3PXbMBEc" height="1" width="1"/&gt;</description>
            <dc:creator>Travis Illig</dc:creator>
            <guid isPermaLink="false">http://www.paraesthesia.com/archive/2013/03/29/portable-class-library-answers.aspx</guid>
            <pubDate>Fri, 29 Mar 2013 16:58:15 GMT</pubDate>
            <comments>http://www.paraesthesia.com/archive/2013/03/29/portable-class-library-answers.aspx#feedback</comments>
            <wfw:commentRss>http://www.paraesthesia.com/comments/commentRss/1815.aspx</wfw:commentRss>
        <feedburner:origLink>http://www.paraesthesia.com/archive/2013/03/29/portable-class-library-answers.aspx</feedburner:origLink></item>
        <item>
            <title>Gave Up Trying FxCop 11 Standalone</title>
            <category>.NET</category>
            <category>Visual Studio</category>
            <link>http://feedproxy.google.com/~r/Paraesthesia/~3/sE_BDZJRX20/gave-up-trying-fxcop-11-standalone.aspx</link>
            <description>&lt;p&gt;In FxCop 10 you could run code analysis without installing Visual Studio by either &lt;a href="http://www.paraesthesia.com/archive/2010/03/29/updating-your-continuous-integration-build-to-run-fxcop-from-vs2010.aspx" target="_blank"&gt;grabbing just the FxCop stuff out of Visual Studio&lt;/a&gt; or installing the Windows SDK.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Not so, with FxCop 11. There's no longer a standalone installer - it's been removed from the Windows SDK.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I tried grabbing the FxCop out of Visual Studio 2012 and it fails with the exception: &lt;code&gt;System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.VisualStudio.CodeAnalysis.Interop.dll' or one of its dependencies. The specified module could not be found.&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Using &lt;a href="http://www.dependencywalker.com/" target="_blank"&gt;Dependency Walker&lt;/a&gt; on &lt;code&gt;Microsoft.VisualStudio.CodeAnalysis.Interop.dll&lt;/code&gt;, you can see a ton of missing assembly references:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;code&gt;msvcp110.dll&lt;/code&gt;&lt;/li&gt;   &lt;code&gt;     &lt;li&gt;msvcr110.dll&lt;/li&gt;   &lt;/code&gt;    &lt;li&gt;&lt;code&gt;ieshims.dll&lt;/code&gt;&lt;/li&gt;   &lt;code&gt;     &lt;li&gt;mf.dll&lt;/li&gt;   &lt;/code&gt;&lt;code&gt;     &lt;li&gt;mfplat.dll&lt;/li&gt;   &lt;/code&gt;&lt;code&gt;     &lt;li&gt;mfreadwrite.dll&lt;/li&gt;   &lt;/code&gt;    &lt;li&gt;&lt;code&gt;wlanapi.dll&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The &lt;code&gt;msvc*.dll &lt;/code&gt;assemblies are part of &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=30679" target="_blank"&gt;the Visual C++ redistributable&lt;/a&gt;, so I tried installing that and it did fix those issues. The ieshims.dll is part of Internet Explorer, so adding &lt;code&gt;C:\Program Files\Internet Explorer &lt;/code&gt;to the path fixed that. The &lt;code&gt;mf*.dll &lt;/code&gt;files, though… that's media related. Like, "Media Player" style. I've seen places that you can get that with WPF bits.&lt;/p&gt;  &lt;p&gt;I made sure my build server had all the latest patches after dealing with the Visual C++ and IE stuff, and… then I got more failures. Stuff about "api-win-core-somethingorother.dll" and some WinRT(?!) stuff.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;ARGH.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;FxCop was added to the Visual Studio Express family, &lt;strong&gt;but &lt;/strong&gt;&lt;a href="http://blogs.msdn.com/b/codeanalysis/archive/2012/03/08/what-s-new-in-code-analysis-for-visual-studio-11.aspx" target="_blank"&gt;&lt;strong&gt;the blog article on it&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; doesn't tell you which Visual Studio Express has it&lt;/strong&gt;. Turns out the Visual Studio Express for Web &lt;em&gt;does not&lt;/em&gt; include it.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Visual Studio Express for Windows Desktop has FxCop in it&lt;/strong&gt;, so that's what you have to install to get FxCop up and running. I presume the Express for Windows 8 version also has it, &lt;em&gt;but I don't know and I didn't check&lt;/em&gt;. I'm kind of surprised the web one doesn't come with FxCop.&lt;/p&gt;  &lt;p&gt;So… there you go. &lt;strong&gt;You have to install Visual Studio on your build server if you want FxCop&lt;/strong&gt;. (Or you have to chase down all the chained-in dependencies and drag them along with your local version, in which case, &lt;em&gt;good luck with that&lt;/em&gt;.)&lt;/p&gt;  &lt;p&gt;Note that, even with VS Express installed, I still failed with an error when running from the command line: &lt;code&gt;Failed to add rule assembly: c:\program files (x86)\microsoft visual studio 11.0\team tools\static analysis tools\fxcop\Rules\DataflowRules.dll&lt;/code&gt;. Looking in the folder, sure enough, it's missing. I don't see anything referencing that assembly, but it's there in a VS Premium installation, so… what gives?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In fact, there's a lot missing from the Express version of FxCop that is there in Premium.&lt;/strong&gt; Like… &lt;em&gt;the whole Phoenix analysis engine is totally missing&lt;/em&gt;. What gives? Honestly, I ended up not only having to install VS Express, but also copy over the missing stuff into &lt;code&gt;C:\Program Files (x86)\Microsoft Visual Studio 11.0\Team Tools\Static Analysis Tools\FxCop &lt;/code&gt;so I could get apples-to-apples builds on my build server and dev machines. (Alternatively, I guess you could install VS Premium on the build server since, &lt;em&gt;hell, you're already installing Visual Studio, so you lost that battle&lt;/em&gt;.)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;In the end, I had to install Visual Studio 2012 Premium on the build server&lt;/strong&gt; in order to get things working. Yeah, you read that right. I mean, if you already have &lt;em&gt;two different Express SKUs installed and still didn't get the entirety of FxCop&lt;/em&gt;, it's time to stop messing about.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;I can't say this leaves me happy.&lt;/strong&gt; I'm baffled as to why this doesn't "just work." FxCop is a standalone thing. It doesn't make sense that you couldn't just install it as part of the Windows SDK or a .NET SDK or something. Kind of makes me wonder if it's an indirect sales ploy to get you to convert to TFS or something.&lt;/p&gt;&lt;img src="http://www.paraesthesia.com/aggbug/1814.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=sE_BDZJRX20:qBBNcJyspoI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=sE_BDZJRX20:qBBNcJyspoI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=sE_BDZJRX20:qBBNcJyspoI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=sE_BDZJRX20:qBBNcJyspoI:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=sE_BDZJRX20:qBBNcJyspoI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=sE_BDZJRX20:qBBNcJyspoI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=sE_BDZJRX20:qBBNcJyspoI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=sE_BDZJRX20:qBBNcJyspoI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=sE_BDZJRX20:qBBNcJyspoI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Paraesthesia/~4/sE_BDZJRX20" height="1" width="1"/&gt;</description>
            <dc:creator>Travis Illig</dc:creator>
            <guid isPermaLink="false">http://www.paraesthesia.com/archive/2013/03/12/gave-up-trying-fxcop-11-standalone.aspx</guid>
            <pubDate>Tue, 12 Mar 2013 20:36:20 GMT</pubDate>
            <comments>http://www.paraesthesia.com/archive/2013/03/12/gave-up-trying-fxcop-11-standalone.aspx#feedback</comments>
            <wfw:commentRss>http://www.paraesthesia.com/comments/commentRss/1814.aspx</wfw:commentRss>
        <feedburner:origLink>http://www.paraesthesia.com/archive/2013/03/12/gave-up-trying-fxcop-11-standalone.aspx</feedburner:origLink></item>
        <item>
            <title>Adding Custom Files to an MSDeploy Package</title>
            <category>.NET</category>
            <category>Web Development</category>
            <link>http://feedproxy.google.com/~r/Paraesthesia/~3/bdf3CWWXi9w/adding-custom-files-to-an-msdeploy-package.aspx</link>
            <description>&lt;p&gt;As part of some of my web projects I have "plugin assemblies" that aren't directly referenced by the project but are things I want included in my deployment package. I tried following the instructions &lt;a href="http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx" target="_blank"&gt;on this fairly popular blog entry&lt;/a&gt;, but it didn't seem to work - that blog entry tells you to modify a set of files during a stage in the packaging pipeline "&lt;code&gt;CopyAllFilesToSingleFolderForPackageDependsOn&lt;/code&gt;" and that target never actually fired for me. In fact, I threw an &amp;lt;Error&amp;gt; call in there just to see if I could get the build to fail and… no luck.&lt;/p&gt;  &lt;p&gt;It also seems that manually copying the files over into the deployment staging/temporary folder stopped working - you can copy them over, but they instantly get deleted just before packaging occurs.&lt;/p&gt;  &lt;p&gt;Turns out a lot of the way the MSDeploy packaging stuff in &lt;code&gt;Microsoft.WebApplication.targets&lt;/code&gt; works changed in Visual Studio 2012 and… it's like no one out there noticed. Or maybe everyone solved the problem and forgot to blog it. Or maybe I'm some special edge case. Anyway, it took some serious reverse-walkthrough of the packaging process to figure out what needs to happen. (Yeah, that was a day wasted.)&lt;/p&gt;  &lt;p&gt;Now, instead of "&lt;code&gt;CopyAllFilesToSingleFolderForPackageDependsOn&lt;/code&gt;" for the event to handle, use "&lt;code&gt;PipelineCopyAllFilesToOneFolderForMsdeployDependsOn&lt;/code&gt;" for including your custom files. Once you do that, you don't have to copy the files into the staging area or anything; the packaging process will do that for you.&lt;/p&gt;  &lt;p&gt;Something else that changed - the "&lt;code&gt;Package&lt;/code&gt;" target in &lt;code&gt;Microsoft.WebApplication.targets&lt;/code&gt; seems to rely on the "&lt;code&gt;Build&lt;/code&gt;" target in some cases. I tried setting the property so "&lt;code&gt;Package&lt;/code&gt;" wouldn't rely on "&lt;code&gt;Build&lt;/code&gt;" (&lt;code&gt;PipelineDependsOnBuild&lt;/code&gt;) but it always ended up doing some portion of "&lt;code&gt;Build&lt;/code&gt;." The problem there is that "&lt;code&gt;Build&lt;/code&gt;"(from &lt;code&gt;Microsoft.Common.targets&lt;/code&gt;) wants to run a target called "&lt;code&gt;IntermediateClean&lt;/code&gt;" that deletes a bunch of stuff out of your &lt;code&gt;bin&lt;/code&gt; folder - even assemblies that were built due to project references. (This happens more during a command line build than during a VS build. They're treated differently… which is pretty annoying.) What this means is you have to "fool" the "&lt;code&gt;IntermediateClean&lt;/code&gt;" during the packaging process so it doesn't clean out your plugins. You do that by setting a "magic" item called &lt;code&gt;FileWrites&lt;/code&gt; to contain all the stuff you want to keep.&lt;/p&gt;  &lt;p&gt;Here's a snippet from my web project .csproj file showing how I just include everything in the bin folder since I want all the copied-in dependencies to be kept for the packaging:&lt;/p&gt;  &lt;pre&gt;&amp;lt;PropertyGroup&amp;gt;
  &amp;lt;PipelineCopyAllFilesToOneFolderForMsdeployDependsOn&amp;gt;
    IncludePluginFilesForMsdeploy;
    $(PipelineCopyAllFilesToOneFolderForMsdeployDependsOn);
  &amp;lt;/PipelineCopyAllFilesToOneFolderForMsdeployDependsOn&amp;gt;
&amp;lt;/PropertyGroup&amp;gt;
&amp;lt;Target Name="IncludePluginFilesForMsdeploy"&amp;gt;
  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;FileWrites Include="$(MSBuildProjectDirectory)\bin\**\*" /&amp;gt;
    &amp;lt;_CustomFiles Include="$(MSBuildProjectDirectory)\bin\**\*" /&amp;gt;
    &amp;lt;FilesForPackagingFromProject Include="%(_CustomFiles.Identity)"&amp;gt;
      &amp;lt;DestinationRelativePath&amp;gt;bin\%(RecursiveDir)%(Filename)%(Extension)&amp;lt;/DestinationRelativePath&amp;gt;
    &amp;lt;/FilesForPackagingFromProject&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&amp;lt;/Target&amp;gt;&lt;/pre&gt;

&lt;p&gt;That all has to go &lt;em&gt;after&lt;/em&gt; the line that imports the &lt;code&gt;Microsoft.WebApplication.targets&lt;/code&gt; file.&lt;/p&gt;&lt;img src="http://www.paraesthesia.com/aggbug/1813.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bdf3CWWXi9w:oL2kjUzb4oQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bdf3CWWXi9w:oL2kjUzb4oQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=bdf3CWWXi9w:oL2kjUzb4oQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bdf3CWWXi9w:oL2kjUzb4oQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bdf3CWWXi9w:oL2kjUzb4oQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=bdf3CWWXi9w:oL2kjUzb4oQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bdf3CWWXi9w:oL2kjUzb4oQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=bdf3CWWXi9w:oL2kjUzb4oQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=bdf3CWWXi9w:oL2kjUzb4oQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Paraesthesia/~4/bdf3CWWXi9w" height="1" width="1"/&gt;</description>
            <dc:creator>Travis Illig</dc:creator>
            <guid isPermaLink="false">http://www.paraesthesia.com/archive/2013/03/08/adding-custom-files-to-an-msdeploy-package.aspx</guid>
            <pubDate>Fri, 08 Mar 2013 17:09:29 GMT</pubDate>
            <comments>http://www.paraesthesia.com/archive/2013/03/08/adding-custom-files-to-an-msdeploy-package.aspx#feedback</comments>
            <wfw:commentRss>http://www.paraesthesia.com/comments/commentRss/1813.aspx</wfw:commentRss>
        <feedburner:origLink>http://www.paraesthesia.com/archive/2013/03/08/adding-custom-files-to-an-msdeploy-package.aspx</feedburner:origLink></item>
        <item>
            <title>2013 Vegas Vacation</title>
            <category>General Ramblings</category>
            <link>http://feedproxy.google.com/~r/Paraesthesia/~3/WcneqHQ5oF0/2013-vegas-vacation.aspx</link>
            <description>&lt;p&gt;Every year, maybe every other year, Jenn and I head down to Las Vegas. There’s always something new to check out and it’s a fun place to visit.&lt;/p&gt;  &lt;p&gt;This time we stayed at &lt;a href="http://www.arialasvegas.com/" target="_blank"&gt;ARIA&lt;/a&gt; again since we enjoyed it so much last time. It’s a nice place with lots of great amenities, and we got a pretty good deal so off we went. (We left Phoenix with Grandma and Grandpa Illig.)&lt;/p&gt;  &lt;p&gt;Normally we kind of do the same stuff – we run ourselves ragged walking up and down the strip trying to see every hotel and visit every shop. What we’ve found, though, is that while we tire ourselves out, there’s not that much changing (it changes fast, but not that fast) so we haven’t actually seen a lot of new stuff. This time we decided to make a point to both not walk our feet off &lt;em&gt;and&lt;/em&gt; see new stuff we’d not seen before.&lt;/p&gt;  &lt;p&gt;The first night we were there we hit the Fremont Street Experience. We had heard about it a lot, but hadn’t ever made it down there. It was well worth it – there was a lot to see. We rode the zip lines down the street, watched like three or four bands perform, and found where they hid the $5 blackjack tables (&lt;a href="http://goldengatecasino.com/" target="_blank"&gt;the Golden Gate&lt;/a&gt;). We don’t really gamble, but we had a lot of fun playing. (I think I rode $20 for like an hour. I lost, but I got my money’s worth.)&lt;/p&gt;  &lt;p&gt;&lt;a href="https://plus.google.com/photos/100275637557074554059/albums/5850895904343810865/5850896036582032050" target="_blank"&gt;&lt;img title="" alt="Travis riding the zip line" src="https://lh5.googleusercontent.com/-dvR0z8ttQ4k/UTKO8iY2grI/AAAAAAAAH7M/QnwkAZ36SjM/s400/20130224_193500.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Only downside to the Fremont Street thing is how far away it is from the strip. We took a taxi and it was like $25 each way (not counting tip). If you plan on checking that out, you either need to figure out public transportation, rent a car, or actually stay down there.&lt;/p&gt;  &lt;p&gt;Another thing we did that I wanted to do since last time we were there was check out &lt;a href="http://www.minus5experience.com/" target="_blank"&gt;the Minus 5 ice bar&lt;/a&gt;. The whole place is a big freezer where the walls are lined with blocks of ice, the furniture is made of ice, and even the cups you drink out of are ice. It is, as you can imagine, totally freezing in there. Like, you get a parka and some gloves along with your admission, but even with that you start to go numb in your fingers and toes after a while. You have to set your drink down on a neoprene coaster, too, since the cup and the table are ice and your cup will fly right off like an air hockey puck. (We played with that for a while.) There are sculptures and things made out of ice to check out, and there was a cool little “living room setting” made out of ice where they had a fireplace (the “fire” was a decal frozen in the ice) and on the mantel were a bunch of books – all frozen in a block of ice. It was fun and pretty novel.&lt;/p&gt;  &lt;p&gt;&lt;a href="https://plus.google.com/photos/100275637557074554059/albums/5850895904343810865/5850896446873685186" target="_blank"&gt;&lt;img title="" alt="Jenn and Travis at Minus 5" src="https://lh6.googleusercontent.com/-hitJVaj_6i8/UTKPUa2ATMI/AAAAAAAAH7c/fQxs8hUqV2o/s400/20130225_223547.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We ate at a couple of new places (&lt;a href="http://www.cosmopolitanlasvegas.com/taste/restaurant-collection/wicked-spoon.aspx" target="_blank"&gt;the Wicked Spoon buffet&lt;/a&gt; is a new favorite), and we visited some of the same stores, but for the most part, we otherwise just really took it easy. We actually did accomplish our goal – not walking our feet off and trying a bunch of new stuff. It was good to get home and sleep in my own bed… but I could stand to go back in a few months. I always have a good time.&lt;/p&gt;  &lt;p&gt;&lt;a href="https://plus.google.com/photos/100275637557074554059/albums/5850895904343810865" target="_blank"&gt;Here’s the full photo album in case you’re interested&lt;/a&gt;. Lots of decorations all over for Chinese New Year.&lt;/p&gt;&lt;img src="http://www.paraesthesia.com/aggbug/1812.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=WcneqHQ5oF0:U4wmvOM5FhE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=WcneqHQ5oF0:U4wmvOM5FhE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=WcneqHQ5oF0:U4wmvOM5FhE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=WcneqHQ5oF0:U4wmvOM5FhE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=WcneqHQ5oF0:U4wmvOM5FhE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=WcneqHQ5oF0:U4wmvOM5FhE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=WcneqHQ5oF0:U4wmvOM5FhE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=WcneqHQ5oF0:U4wmvOM5FhE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=WcneqHQ5oF0:U4wmvOM5FhE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Paraesthesia/~4/WcneqHQ5oF0" height="1" width="1"/&gt;</description>
            <dc:creator>Travis Illig</dc:creator>
            <guid isPermaLink="false">http://www.paraesthesia.com/archive/2013/03/02/2013-vegas-vacation.aspx</guid>
            <pubDate>Sun, 03 Mar 2013 00:18:15 GMT</pubDate>
            <comments>http://www.paraesthesia.com/archive/2013/03/02/2013-vegas-vacation.aspx#feedback</comments>
            <wfw:commentRss>http://www.paraesthesia.com/comments/commentRss/1812.aspx</wfw:commentRss>
        <feedburner:origLink>http://www.paraesthesia.com/archive/2013/03/02/2013-vegas-vacation.aspx</feedburner:origLink></item>
        <item>
            <title>Can You Run Visual Studio in Azure?</title>
            <category>.NET</category>
            <category>Visual Studio</category>
            <link>http://feedproxy.google.com/~r/Paraesthesia/~3/kBVXnBnLOOE/can-you-run-visual-studio-in-azure.aspx</link>
            <description>&lt;p&gt;I was sitting at the car repair place on Saturday with my Surface RT thinking it'd be nice to have a Visual Studio instance to tinker with. Given I have an MSDN subscription that comes with a free Azure VM and Visual Studio, it made sense to me that I could just set up the VM with Visual Studio and play on that.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;It doesn't look like licensing allows you to do that.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I'm still waiting to &lt;a href="https://twitter.com/blowdart/status/302850244041928705" target="_blank"&gt;hear something somewhat "official" from Barry Dorrans (@blowdart)&lt;/a&gt; but &lt;a href="https://twitter.com/markjbrown/status/302886731898826752" target="_blank"&gt;Mark Brown (@markjbrown, an Azure community person) says you can't do that&lt;/a&gt;, and my research agrees with Mark. Here's what I've put together:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.windowsazure.com/en-us/pricing/licensing-faq/" target="_blank"&gt;The Azure licensing FAQ&lt;/a&gt; says you can't install Windows 7 or Office in Azure because &lt;strong&gt;they're classified as "Desktop Applications"&lt;/strong&gt; and can't run on virtual machines. There's also a question about running MSDN licensed items in the cloud indicating you can't extend your rights there. I'll copy/paste those here:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Q: Can customers run Microsoft Office and Windows 7 Client on Virtual Machines?        &lt;br /&gt;A:&lt;/strong&gt; No.  Under the Microsoft Product Usage Rights (PUR), Office and Windows 7 are not licensed to run on Virtual Machines.  In particular, Microsoft Office is classified in the PUR as “Desktop Applications”, which is not included in Licensing Mobility.&lt;/p&gt;    &lt;p&gt;More information is available at the site for &lt;a href="http://www.microsoft.com/licensing/about-licensing/product-licensing.aspx" target="_blank"&gt;Microsoft Product Use Rights&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Q: Can a customer extend their MSDN use rights to the cloud?&lt;/strong&gt;       &lt;br /&gt;&lt;strong&gt;A:&lt;/strong&gt; No, the software licensed under MSDN subscriptions is not for use in cloud environments.  However, most MSDN subscribers are entitled to a significant amount of Windows Azure services as a benefit of their subscription and can use these benefits to run instances of Windows Server on the Windows Azure IaaS or to run Windows Azure PaaS services.  For details on the amount of Windows Azure services included with MSDN subscriptions, please see &lt;a href="http://www.windowsazure.com/en-us/pricing/member-offers/msdn-benefits/"&gt;http://www.windowsazure.com/en-us/pricing/member-offers/msdn-benefits/&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;To run a VM including Microsoft server software such as SharePoint Server, Exchange Server, SQL Server, or BizTalk Server in a Windows Azure VM, an MSDN subscriber could use their Windows Azure benefits to cover the usage of the Windows Azure services and Windows Server running in the VM, then use license mobility on server licenses that their organization has covered under Software Assurance in order to run instances of the server software in the VM.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Following that &lt;a href="http://www.microsoft.com/licensing/about-licensing/product-licensing.aspx" target="_blank"&gt;Product Use Rights&lt;/a&gt; link, you can get the latest product list document and you'll see that &lt;strong&gt;Visual Studio is also classified as a "Desktop Application,"&lt;/strong&gt; so I have to assume it's considered in the same way Office and Windows 7 are.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;UPDATE 2/20/2013&lt;/strong&gt;: Looking at &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=13350" target="_blank"&gt;the Visual Studio 2012 and MSDN Licensing White Paper&lt;/a&gt;, there's this section:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;When Virtual Environments Require a Separate License&lt;/p&gt;    &lt;p&gt;If a physical machine running one or more virtual machines is used entirely for development and test, then the operating system used on the physical host system can be MSDN software. However, if the physical machine or any of the VMs hosted on that physical system are used for other purposes, then both the operating system within the VM and the operating system for the physical host must be licensed separately. The same holds true for other software used on the system—for example, Microsoft SQL Server obtained as MSDN software can only be used to design, develop, test, and demonstrate your programs.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I can see how Azure is a cloudy (haha) area here because the physical hardware backing it is hosting multiple VMs - some are production sites, some are dev/test.&lt;/p&gt;  &lt;p&gt;It also appears there is some discrepancy in interpretation of whether or not you can use Windows 7 on a VM. &lt;a href="http://blogs.technet.com/b/simonmay/archive/2011/01/13/windows-7-licensing-and-virtual-machines-clarified.aspx" target="_blank"&gt;It looks like if you have certain licenses for it, you actually can run Windows 7 in a VM&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;This makes me re-think whether or not you really can use Visual Studio in the cloud&lt;/strong&gt;. I'm less certain than I was when I posted the original article&lt;/p&gt;  &lt;p&gt;From a personal standpoint, if you can't use VS in the cloud… &lt;em&gt;I think that's dumb&lt;/em&gt;. From a business standpoint, if a company wanted to pay for Azure VM resources to host all of their dev machines or something in the cloud so you can stamp them out easily, scale up or down… why not? Sounds like a missed opportunity to me. But even if you ignore that, I feel like Visual Studio should be a kind of "special case" app. Yeah, it's a desktop app, but there are different reasons you'd want to install it in places like Azure so I don't know why you'd restrict it. Maybe they'll change it in the future. Maybe they'll extend MSDN licensing to allow for that special case or something. I hope they do. Until then… looks like I don't get to dev on my Surface RT unless I want to set up the hosting for that myself… &lt;em&gt;on a real, physical machine&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Standard disclaimers apply here.&lt;/strong&gt; Doubly so because we're in legal territory. I'm no lawyer, and I don't know if you or your company negotiated different licensing. I don't know about all the different crazy combinations of licensing out there and there's a lot of craziness around licensing you need to be aware of to be fully compliant. For me, &lt;strong&gt;I'd recommend erring on the side of caution&lt;/strong&gt; - if you don't know for sure, don't do it. Check with your Microsoft rep or company or whatever to find out for sure. I'm just providing the above research to show you what I found and maybe help inform you. If it turns out I'm wrong… let me know (and provide some docs I can refer to). I'll be happy to update the article.&lt;/p&gt;&lt;img src="http://www.paraesthesia.com/aggbug/1811.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=kBVXnBnLOOE:iSxqcjcSPdw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=kBVXnBnLOOE:iSxqcjcSPdw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=kBVXnBnLOOE:iSxqcjcSPdw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=kBVXnBnLOOE:iSxqcjcSPdw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=kBVXnBnLOOE:iSxqcjcSPdw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=kBVXnBnLOOE:iSxqcjcSPdw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=kBVXnBnLOOE:iSxqcjcSPdw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Paraesthesia?a=kBVXnBnLOOE:iSxqcjcSPdw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Paraesthesia?i=kBVXnBnLOOE:iSxqcjcSPdw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Paraesthesia/~4/kBVXnBnLOOE" height="1" width="1"/&gt;</description>
            <dc:creator>Travis Illig</dc:creator>
            <guid isPermaLink="false">http://www.paraesthesia.com/archive/2013/02/18/can-you-run-visual-studio-in-azure.aspx</guid>
            <pubDate>Mon, 18 Feb 2013 18:57:32 GMT</pubDate>
            <comments>http://www.paraesthesia.com/archive/2013/02/18/can-you-run-visual-studio-in-azure.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://www.paraesthesia.com/comments/commentRss/1811.aspx</wfw:commentRss>
        <feedburner:origLink>http://www.paraesthesia.com/archive/2013/02/18/can-you-run-visual-studio-in-azure.aspx</feedburner:origLink></item>
    </channel>
</rss>
