【问题标题】:MVC 5 - Resolving DataAnnotations at runtimeMVC 5 - 在运行时解析 DataAnnotations
【发布时间】:2019-07-30 02:27:12
【问题描述】:

我们需要根据项目的性质和配置在运行时解析 dataAnnotations。显然,其中一个选项(最好不使用自定义属性)是继承 DataAnnotationsModelValidatorProvider 并覆盖其 GetValidators 方法。稍后在 global.axax.cs 中将新类添加为 ModelValidatorProviders.Providers.Add(new CustomCoolProvider());

问题:这对 MVC 5 仍然有效吗?

这个实现背后的想法是替换一些设置为数据注释的格式化值,例如:[Display(Name="COOL.VALUE")]将被理解并替换为一些其他值:metadata.DisplayName = "Some super cool value"

这里有人为先前版本的 MVC 编写了一个示例。 DataAnnotations dynamically attaching attributes

感谢您的帮助。

【问题讨论】:

  • 如果您阅读了该文章中的最后一个答案,它明确表示 DisplayAttribute 不适用于该方法,因为它仅适用于 ValidationAttribute。 DataAttributes 在编译时编译到应用程序中,并且不能在运行时更改。 ValidationAttribute 技术起作用的唯一原因是 ValidationAttributes 有一个内置的钩子来允许它,其他属性没有这个。
  • 那么,如何覆盖 display.name 的值?
  • 你不能。这是 DataAttributes 的主要限制之一。
  • 好的,自定义属性可以吗?如何在 MVC 中构建 i18n?
  • 资源字符串可以存入数据库吗?

标签: asp.net-mvc model-view-controller asp.net-mvc-5 data-annotations


【解决方案1】:

这是我们用来处理数据注释的。在您的 global.asax.cs 文件中。

protected void Application_Start() {
    ...
    ModelMetadataProviders.Current=new MyMetadataProvider();
    ...
}

private 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);

        //Automatically replace underscores with spaces and remove the "id" from the end of column names
        if(metadata.DisplayName==null&&propertyName!=null) {
            metadata.DisplayName=propertyName.Replace('_',' ');
            if(metadata.DisplayName.ToLower().EndsWith(" id"))
                metadata.DisplayName=metadata.DisplayName.Remove(metadata.DisplayName.Length-3);
        }

        //Automatically attribute multiline for anything 500 chars and above (or strings with no length defined)
        if(modelType==typeof(string)&&!(attributes.OfType<StringLengthAttribute>()?.FirstOrDefault()?.MaximumLength<500))
            metadata.DataTypeName="MultilineText";

        //Automatically attribute dates (not datetime)
        if(attributes.OfType<ColumnAttribute>()?.FirstOrDefault()?.TypeName?.ToLower()=="date") {
            metadata.DataTypeName="Date";
            metadata.EditFormatString="{0:yyyy-MM-dd}";
        }

        return metadata;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    相关资源
    最近更新 更多