Обновление DisplayName без присвоения свойства

#c# #asp.net-mvc

#c# #asp.net-mvc

Вопрос:

Мне нужно использовать существующий объект в качестве свойства в моей модели, к которому я не могу применить атрибут DisplayNameAttribute при компиляции файла.

Это сложный и глубокий объект, и этот шаблон необходимо повторять — я не хочу создавать над ним оболочку, если мне это абсолютно необходимо.

Я считаю, что наиболее подходящий способ сделать это — вручную установить атрибут DisplayName в классе ModelMetadata.

Мне удалось найти свойства и установить атрибут отображения, используя приведенный ниже код:

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

Изменения, внесенные во второй строке, не влияют на «источник истины», то есть каждый раз, когда выполняется первая строка DisplayName , для свойства on FirstName устанавливается значение null.

Как я могу обойти это? Это в обычном методе MVC.

Ответ №1:

Вы можете переопределить 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

 protected void Application_Start() {

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