title: ASP.NET MVC Model Binding and Validation Order
body: <p>I have a model (simplified) as follows:</p>
  
  <pre><code>public UserModel {
      ...
      public USState State {get; set; }
      public string StateString {get; set; }
      public Country Country {get; set; }
      ...
  }
  </code></pre>
  
  <p>The validation rules I need are:</p>
  
  <ol>
  <li>If <code>Country</code> is <em>USA</em> then <code>State</code> is required.</li>
  <li>If <code>Country</code> is not <em>USA</em> then <code>StateString</code> is required.</li>
  </ol>
  
  <p>I've created a custom validation attribute <code>RequiredIfAttribute</code>. This works fine so I'm not going to fill the question with it's implementation. It has three required members:</p>
  
  <ol>
  <li><code>CompareField</code> - This is the field it will use to check whether or not validation is required. </li>
  <li><code>CompareValue</code> - This is the value it will compare to to decide whether or not validation is required.</li>
  <li><code>CompareType</code> - This is how it will compare the value to decide whether or not validation is required.</li>
  </ol>
  
  <p>So with this, I update my model as such:</p>
  
  <pre><code>public UserModel {
      ...
      [RequiredIf("Country", Country.USA, EqualityType.Equals)]    
      public USState State {get; set; }
      [RequiredIf("Country", Country.USA, EqualityType.NotEquals)] 
      public string StateString {get; set; }
      [Required]                                                   
      public Country Country {get; set; }
      ...
  }
  </code></pre>
  
  <p>I should note here that my <code>RequiredIfAttribute</code> also has client side validation. This works perfectly.</p>
  
  <p>Now on to the problem...</p>
  
  <p>I'm posting the following values:</p>
  
  <blockquote>
    <p>State = <em>AL</em> <br />
    StateString = <em>null</em> <br />
    Country = <em>USA</em></p>
  </blockquote>
  
  <p>This meets my validation rules and should be valid. Here's the <em>but</em>. <code>ModelState</code> is telling me it is not valid. Apparently by StateString field is required. That's not what I specified. Why aren't my validation rules applied as expected?</p>
  
  <p><em><strong>(If you know what's wrong at this point, then don't feel obliged to read the rest of the question)</em></strong></p>
  
  <p>So here's what's happening. The <code>RequiredIfAttribute</code> is being triggered three times. But wait, I'm only using it twice. It is is being triggered like so:</p>
  
  <ol>
  <li>Trigger on <code>StateString</code> (this comes back <strong>invalid</strong>)</li>
  <li>Trigger on <code>State</code> (this comes back <strong>valid</strong>)</li>
  <li>Trigger on <code>StateString</code> (this comes back <strong>valid</strong>)</li>
  </ol>
  
  <p>This is pretty odd. It's validating <code>StateString</code> twice, first time it passes, second time it fails. The plot thickens...</p>
  
  <p>I looked into this further to find that the first time it tries to validate <code>StateString</code>, <code>Country</code> <strong>is not</strong> set. The second time it tries to validate <code>StateString</code>, <code>Country</code> <strong>is</strong> set. Looking closer, it seem that the first attempt to validate <code>StateString</code> has occurred before my model has been fully bound. All properties (not listed in the sample model) that are below <code>StateString</code> (in code) are not bound. The second attempt to validate <code>StateString</code>, all properties are bound.</p>
  
  <p>I have solved the problem, but I'm not confident in it because I simply do not trust it. To get my validation to work as expected, I rearranged the model as such (attributes removed for brevity):</p>
  
  <pre><code>public UserModel {
      ...
      public Country Country {get; set; }
      public USState State {get; set; }
      public string StateString {get; set; }
      ...
  }
  </code></pre>
  
  <p>The <code>RequiredIfAttribute</code> still triggers three times as above but <code>ModelState</code> tells me that the posted data (as above) is now valid, like magic! </p>
  
  <p>What I'm seeing is this (my assumptions):</p>
  
  <pre><code>1. Start binding (property by property, top to bottom in code (risky))
  2. Arrive at `StateString` and decide to try and validate
  3. Finish binding
  4. Validate all properties
  </code></pre>
  
  <p><strong>I really have two questions:<br />
   1. Why is this behaviour exhibited?<br />
   2. How can I stop this behaviour?</strong></p>