Ответ 1
Вот некоторое представление о том, что неправильно.
Mvc использует форму TypeDescriptor (AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type)
) для чтения атрибутов с ваших моделей. TypeDescriptors кэширует информацию о свойствах и атрибутах. Таким образом, ваш атрибут LocalizedDisplayFormatAttribute
получает экземпляр только один раз, с точки зрения TypeDescriptor api, что означает, что информация о ресурсе считывается только один раз (при построении). См. Нижнюю часть ответа для ссылок.
Решения, которые не работают
-
Реакция мигания заключается в том, чтобы просто вытащить последнюю информацию о ресурсах из вашего
LocalizedDisplayFormatAttribute NullDisplayText
каждый раз, когда к нему обращаются через геттер. К сожалению,DisplayFormatAttribute
NullDisplayText
не является виртуальным, и вы затеняете свойство с помощью ключевого словаnew
. Это не сработает с точки зрения полиморфной диспетчеризации (Mvc вызывает геттер какDisplayFormatAttribute
вместоLocalizedDisplayFormatAttribute
, поэтому ваше теневое свойство никогда не вызывается) -
Я пробовал перегружать
TypeDescriptor.Refresh()
https://msdn.microsoft.com/en-us/library/z1ztz056(v=vs.110).aspx и не повезло
Остальные варианты, о которых я знаю, не так удобны или не удивительны так или иначе. Вероятно, не рекомендуется.
- Как можно успешно обновить
AssociatedMetadataTypeTypeDescriptionProvider TypeDescriptors
. Я не слишком хорошо знаком с ними, поэтому вполне может быть один. Я просто не вижу его в настоящее время. - Восстановите или создайте
ModelMetadataProvider
самостоятельно. Все это с открытым исходным кодом, поэтому его возможно, хотя я не уверен, что рекомендую его, кроме как в крайнем случае. - Возможно, вы можете работать с Api TypeDescriptor для принудительного повторного создания вашего атрибута всякий раз, когда он вытягивается. См. fooobar.com/info/239918/....
- Сопоставьте необходимые свойства непосредственно в MVC (как свойства модели, а не атрибуты). Могли бы либо быть совершенно новые свойства, либо вы могли бы иметь какую-то логику в своих исходных свойствах, когда null возвращает что-то другое. Неловко иметь дело с этим.
Ничего хорошего, я знаю. Может быть, это даст кому-то еще достаточно проницательности, чтобы придумать что-то лучше?
Чтобы убедиться в этом сами, см.
https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs CreateMetaData
метод, который вызывает метод SetFromDataTypeAndDisplayAttributes
result.NullDisplayText = displayFormatAttribute.NullDisplayText;
DataAnnotationsModelMetadataProvider
extends AssociatedMetadataProvider
, который является неприемлемым для передачи в атрибутах. В качестве примера рассмотрим метод https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/AssociatedMetadataProvider.cs GetMetadataForProperty
.