在不归因属性的情况下更新DisplayName

时间:2016-10-11 19:37:43

标签: c# asp.net-mvc

我需要在模型中使用现有对象作为属性,在编译文件时我不能将DisplayNameAttribute应用于它。

这是一个复杂而深刻的对象,需要重复这个模式 - 我不想在它上面创建一个包装器,除非我绝对必须这样做。

我认为最合适的方法是在ModelMetadata类上手动设置DisplayName属性。

我设法找到属性并使用以下代码设置display属性:

var metadata = ModelMetadataProviders.Current.GetMetadataForType(null, model.GetType());
metadata.Properties.Where(x => x.PropertyName == "FirstName").Single().DisplayName = "First name";

在第二行上所做的更改不会影响“事实来源” - 也就是说,每次执行第一行时,DisplayName上的FirstName属性都设置为null。

我该如何解决这个问题?这是一种正常的MVC方法。

1 个答案:

答案 0 :(得分:0)

您可以覆盖DataAnnotationsModelMetadataProvider来设置DisplayName(并执行各种其他奇特的操作)。

using System.Web.Mvc;
public class CustomModelMetaDataProvider : DataAnnotationsModelMetadataProvider {

    // called once for each property of the ViewModel
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {

        Func<IEnumerable<Attribute>, ModelMetadata> metadataFactory = attr => base.CreateMetadata(attr, containerType, modelAccessor, modelType, propertyName);
        var metadata = metadataFactory(attributes);

        // set DisplayName depending on ViewModel type and property name
        if (modelType == typeof(CustomModelToOverride)) {
            if (propertyName == "FirstName") {
                metadata.DisplayName = "First name";
            }
            else if (propertyName == "LastName") {
                // ...
            }
        }

        return metadata;
    }
}

Global.asax.cs

中注册此自定义MetaDataProvider
protected void Application_Start() {

    // ...
    var metaDataProvider = new CustomModelMetaDataProvider();
    ModelMetadataProviders.Current = metaDataProvider;
}