Чтобы это работало, вам нужно вручную связать интерфейсы как метаданные для ваших конкретных классов.
Я ожидал, что смогу добавить несколько атрибутов MetadataType, но это не разрешено.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] // Notice AllowMultiple
public sealed class MetadataTypeAttribute : Attribute
Следовательно, это дает ошибку компиляции:
[MetadataType(typeof(IPerson))]
[MetadataType(typeof(IAddress))] // <--- Duplicate 'MetadataType' attribute
public class PersonViewModel : IPersonViewModel
Однако, это работает, если у вас есть только один интерфейс. Поэтому я решил просто связать интерфейсы с помощью AssociatedMetadataTypeTypeDescriptionProvider и обернуть это в другой атрибут.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class MetadataTypeBuddyAttribute : Attribute
{
public MetadataTypeBuddyAttribute(Type modelType, Type buddyType)
{
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(
modelType,
buddyType
),
modelType);
}
}
В моей ситуации (MVC4) атрибуты аннотации данных на моих интерфейсах уже работали. Это потому, что мои модели напрямую реализуют интерфейсы, а не имеют многоуровневое наследование. Однако пользовательские атрибуты проверки, реализованные на уровне интерфейса, не работают.
Только при ручной привязке интерфейсов все пользовательские проверки работают соответственно. Если я правильно понимаю ваш случай, это также решение вашей проблемы.
[MetadataTypeBuddy(typeof(PersonViewModel), typeof(IPerson))]
[MetadataTypeBuddy(typeof(PersonViewModel), typeof(IAddress))]
public class PersonViewModel : IPersonViewModel