1

The first time a user chooses a value from a select list, we show a default option with the text Pick one and value -1.

To help with this we have a custom attribute NotEqualAttribute. When a drop-down list is required we have to use both attributes to get it to work correctly.

Our VM looks something like:

[DisplayName("Pick Role")]  
[UIHint("DropDownList")]  
[Required]  
[NotEqual("-1", "Select value for DropDown")]  
public Int64 DdlSelected { get; set; }  
public List<DDLDispValueCV> DdlSelectedList { get; set; }  

We would prefer to use this:

[DisplayName("Pick Role")]
[UIHint("DropDownList")]
[Required]
public Int64 DdlSelected { get; set; }
public List<DDLDispValueCV> DdlSelectedList { get; set; }

Another StackOverflow question discusses how to make non-nullable properties optional unless the Required property is explicitly set.

I tried to do this, but am confused how to add the new attribute to the IEnumerable<Attribute> collection and/or add it to ModelMetadata in the metadata provider:

public class MyMetaDataProvider : DataAnnotationsModelMetadataProvider
{

    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> 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 => x is RequiredAttribute).Count() > 0;

        // If working with a drop down.
        // And required attribute is present
        // Then add NotEqual attribute
        if ((metadata.TemplateHint != null) && (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<Attribute> newAttrs = attributes.Concat(new[] {newAttr});
                metadata = base.CreateMetadata(newAttrs, containerType, modelAccessor, modelType, propertyName);
                metadata.IsRequired = true;
            }
        }
     }  
}
Community
  • 1
  • 1
Razcer
  • 394
  • 4
  • 17
  • Just curious if you were able to figure this out? We'd also like to dynamically add additonal validation attributes to ModelMetadata. Reason being, our main model class definitions are in a non-mvc class library, which is referenced by our web project. We'd like to add the mvc specific Remote validations to our existing model when used in our web project only. Thanks! – Jeff Brewster Oct 10 '11 at 15:53
  • @Jeff We ended up going a different route to do the validations, based on [Brad Wilson's post](http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html) This approach works very well for us now in our templates. – Razcer Oct 25 '11 at 15:54
  • I normally get around this by having the "pick one" value be an empty string, and the integer property nullable if it isn't required. – Betty Apr 12 '12 at 09:59

0 Answers0