Настроить пользовательский поставщик метаданных для ViewModel
У меня есть ViewModel, для которой нужно иметь возможность динамически устанавливать свойства метаданных. Например, я хотел бы иметь возможность настраивать DisplayName и сообщения об ошибках валидации, используя значение других свойств модели. Я планирую сделать это с пользовательским MetadataProvider, следуя статье Брэда Уилсона.
Я хочу, чтобы поставщик использовался только с выбранными моделями просмотра. Итак, мой вопрос, как мне это настроить? Я видел примеры использования ModelMetadataProviders.Current = new MyModelMetadataProvider()
, но это, вероятно, будет использовать пользовательский поставщик для всех объектов классов модели. Можно ли настроить провайдера для одной ViewModel?
2 ответа
Я уверен, что смена поставщика метаданных текущей модели в ViewModel небезопасна, когда вы начнете привлекать на сайт нескольких пользователей, не говоря уже о потоке-безопасности. Возможно, вы сможете использовать метод атрибута, но вам все равно придется реализовать свой собственный ModelMetadataProvider и установить для него значение "Текущий" в начале вашего приложения, а затем проверить наличие определенных атрибутов и определить, нужно ли возвращать ModelMetaData, если их нет, а затем упасть. до базовой реализации. Хотя, если честно, то количество ограничений, о которых вы говорите, иметь дело только с выбранными моделями представлений, но не иметь права знать или тестировать эти модели представлений? Похоже, вы делаете что-то не так в другом месте...
ОБНОВЛЕНИЕ: Когда мне понадобился поставщик ModelMetadata, я создал поставщика, который выглядит примерно так...
public class MyMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
if ((containerType != typeof(MyType))
return base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
//setup custom ModelMetadata here
}
}
Ты не можешь
Тем не менее, вы можете выступать в качестве прокси для всех других моделей. Что-то вроде:
public class YourProvider<TViewModel>
{
public YourProvider(InnerProvider provider) {}
public ModelMetaData GetMetaData(SomeContext context)
{
if (context.ModelType != typeof(TViewModel))
return _innerProvider.GetMetaData(context);
//Other logic here.
}
}
И, наконец, назначьте его следующим образом:
ModelMetadataProviders.Current
= new MyModelMetadataProvider<CustomViewModel>(ModelMetadataProviders.Current);