title: Customize ModelMetadata with CreateMetadata
body: <p>The first time a user chooses a value from a select list, we show a default option with the text <code>Pick one</code> and value <code>-1</code>.</p>
  
  <p>To help with this we have a custom attribute <code>NotEqualAttribute</code>. When a drop-down list is required we have to use both attributes to get it to work correctly.</p>
  
  <p>Our VM looks something like:</p>
  
  <pre class="lang-cs prettyprint-override"><code>[DisplayName("Pick Role")]  
  [UIHint("DropDownList")]  
  [Required]  
  [NotEqual("-1", "Select value for DropDown")]  
  public Int64 DdlSelected { get; set; }  
  public List&lt;DDLDispValueCV&gt; DdlSelectedList { get; set; }  
  </code></pre>
  
  <p>We would prefer to use this:  </p>
  
  <pre class="lang-cs prettyprint-override"><code>[DisplayName("Pick Role")]
  [UIHint("DropDownList")]
  [Required]
  public Int64 DdlSelected { get; set; }
  public List&lt;DDLDispValueCV&gt; DdlSelectedList { get; set; }
  </code></pre>
  
  <p>Another StackOverflow question discusses how to <a href="https://stackoverflow.com/questions/1662442/asp-net-mvc-modelmetadata-is-there-a-way-to-set-isrequired-based-on-the-require">make non-nullable properties optional unless the <code>Required</code> property is explicitly set</a>.</p>
  
  <p>I tried to do this, but am confused how to add the new attribute to the <code>IEnumerable&lt;Attribute&gt;</code> collection and/or add it to <code>ModelMetadata</code> in the metadata provider:</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class MyMetaDataProvider : DataAnnotationsModelMetadataProvider
  {
  
      protected override ModelMetadata CreateMetadata(IEnumerable&lt;Attribute&gt; attributes, Type containerType, Func&lt;object&gt; modelAccessor, Type modelType, string propertyName)
      {
          var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
  
          // Change how required is marked.
          // If required attribute found mark the IsRequired true, otherwise false.
          metadata.IsRequired = attributes.Where(x =&gt; x is RequiredAttribute).Count() &gt; 0;
  
          // If working with a drop down.
          // And required attribute is present
          // Then add NotEqual attribute
          if ((metadata.TemplateHint != null) &amp;&amp; (metadata.TemplateHint.ToString() == "DropDownList"))
          {
              // only add attribue if required.
              if (metadata.IsRequired)
              {
                  // Add custom attribute NotEqual.
                  NotEqualAttribute newAttr = new NotEqualAttribute("-1", "(Pick One) is not valid selection");
                  IEnumerable&lt;Attribute&gt; newAttrs = attributes.Concat(new[] {newAttr});
                  metadata = base.CreateMetadata(newAttrs, containerType, modelAccessor, modelType, propertyName);
                  metadata.IsRequired = true;
              }
          }
       }  
  }
  </code></pre>