1

StringLengthAttribute既存の ASP.NET MVC 4 プロジェクトの多くのモデルに検証を追加する必要があり、 DataAnnotationsModelMetadataProvider.

および他のいくつかのデータ注釈属性と完全に連携し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);
    }
}

そのため、StringLengthAttribute特別な方法で処理されているようです。それを機能させる方法やより良い実装のアイデアについてのアイデアはありますか?

4

1 に答える 1

1

いじってみたところ、StringLength 属性を起動することもできませんでした。

理想的ではありませんが、別の解決策はグローバルな ModelValidatorProvider クラスを使用することだと思います。確かに、StringLengthAttribute によって提供される組み込みの Javascript を取得できず、独自のロジックを作成することになりますが、後で解決できる問題の迅速な修正になる可能性はありますか?

    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>();
        }
    }

}

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());
    }
于 2012-10-21T17:44:25.513 に答える