Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
205 views
in Technique[技术] by (71.8m points)

c# - How to add validation attribute to model property in TemplateEditor in MVC3

I have a DateTime TemplateEditor and I would like to add regex validation to it. I have a RegularExpression attribute that I could decorate the model with, but I dont want to have to decorate every datetime property in all my models with a regex.

Is there way I can my custom TemplateEditor add the appropriate unobstrusive tags when it renders the textbox for it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Instead of adding your validator in the template, you should insert your validator using a custom ModelMetadataValidatorProvider. First, create your ModelMetadataProvider class:

public class MyModelMetadataValidatorProvider : DataAnnotationsModelValidatorProvider
{

    internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory = Create;
    internal static Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories = new Dictionary<Type, DataAnnotationsModelValidationFactory>() {
        {
            typeof(RegularExpressionAttribute),
            (metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute)
        }
    };

    internal static ModelValidator Create(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute)
    {
        return new DataAnnotationsModelValidator(metadata, context, attribute);
    }

    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        List<ModelValidator> vals = base.GetValidators(metadata, context, attributes).ToList();

        // inject our new validator
        if (metadata.ModelType.Name == "DateTime")
        {
            DataAnnotationsModelValidationFactory factory;

            RegularExpressionAttribute regex = new RegularExpressionAttribute(
                "^(((0?[1-9]|1[012])/(0?[1-9]|1\d|2[0-8])|(0?[13456789]|1[012])/(29|30)|(0?[13578]|1[02])/31)/(19|[2-9]\d)\d{2}|0?2/29/((19|[2-9]\d)(0[48]|[2468][048]|[13579][26])|(([2468][048]|[3579][26])00)))$");
            regex.ErrorMessage = "Invalid date format";
            if (!AttributeFactories.TryGetValue(regex.GetType(), out factory))
                factory = DefaultAttributeFactory;

            vals.Add(factory(metadata, context, regex));
        }

        return vals.AsEnumerable();
    }
}

Next, register your ModelMetadataValidatorProvider in Global.asax.cs in Application_Start.

    ModelValidatorProviders.Providers.Clear();
    ModelValidatorProviders.Providers.Add(new MyModelMetadataValidatorProvider());

Now, when you access a model, a RegularExpressionAttribte will be attached to each DateTime field. You can also extend this to provide a localized DateTime regular expression and message.

counsellorben


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...