简体   繁体   English

通过自定义DataAnnotationsModelMetadataProvider添加StringLengthAttribute

[英]Adding StringLengthAttribute through custom DataAnnotationsModelMetadataProvider

I have a requirement to add StringLengthAttribute validation to a lot of models in the existing ASP.NET MVC 4 project and am trying to do this automatically through my own model metadata provider derived from DataAnnotationsModelMetadataProvider . 我需要将StringLengthAttribute验证添加到现有ASP.NET MVC 4项目中的许多模型中,并且正在尝试通过派生自DataAnnotationsModelMetadataProvider我自己的模型元数据提供程序来自动执行此操作。

It works perfectly with RequiredAttribute and some other data annotation attributes (I get both client-side and server-side validation working), however validation for the string length is not added - find the minimal example below. 它与RequiredAttribute和其他一些数据注释属性(我同时支持客户端验证和服务器端验证)完美配合,但是未添加对字符串长度的验证-请在下面找到最小示例。

public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,
                                                    Type containerType,
                                                    Func<object> modelAccessor,
                                                    Type modelType,
                                                    string propertyName)
    {
        StringLengthAttribute lengthAttribute = new StringLengthAttribute(256);
        attributes = attributes.Union(new[] { lengthAttribute });
        return base.CreateMetadata(attributes,
                                   containerType,
                                   modelAccessor,
                                   modelType,
                                   propertyName);
    }
}

So, looks like StringLengthAttribute it being handled in some special way. 因此,看起来像StringLengthAttribute是以某种特殊方式处理的。 Any ideas on how to make it work or a better implementation idea? 关于如何使其有效的任何想法或更好的实施想法?

After playing around, I couldn't get the StringLength attribute to fire either. 玩了之后,我也无法触发StringLength属性。

Not ideal, but i guess an alternative solution is to the use a global ModelValidatorProvider class. 这并不理想,但是我想一个替代解决方案是使用全局ModelValidatorProvider类。 Granted you won't get the built in Javascript that is provided by the StringLengthAttribute and you'd be writing your own logic, but its a possible quick fix for a problem you can solve later? 当然,您不会得到StringLengthAttribute提供的内置Java脚本,而是要编写自己的逻辑,但是对于可能稍后解决的问题,它可能是快速解决方案吗?

    public class MyCustomModelValidatorProvider : ModelValidatorProvider
{
    public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
    {
        return new List<ModelValidator>() { new MyCustomModelValidator(metadata, context) };
    }

    public class MyCustomModelValidator : ModelValidator
    {
        public MyCustomModelValidator(ModelMetadata metadata, ControllerContext context)
            : base(metadata, context)
        {   }

        public override IEnumerable<ModelValidationResult> Validate(object container)
        {
            var model = this.Metadata.Model; 
            if (model is string)
            {
                var value = model as string;

                if (String.IsNullOrEmpty(value) || value.Length > 256)
                {
                    var validationResult = new ModelValidationResult();
                    validationResult.Message = (this.Metadata.DisplayName ?? this.Metadata.PropertyName) 
                        + " needs to be no more then 256 characters";

                    return new List<ModelValidationResult>() { validationResult };
                }
            }

            return new List<ModelValidationResult>();
        }
    }

}

Add MyCustomModelValidator to the collection in Global.asax 将MyCustomModelValidator添加到Global.asax中的集合中

        protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        // Use LocalDB for Entity Framework by default
        Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);


        ModelValidatorProviders.Providers.Add(new MyCustomModelValidatorProvider());
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM