#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;
}