Я удивлен, что никто не упомянул MetadataTypeAttribute . Но да, это работает.
[MetadataType(typeof(ICustomerMetaData))]
public partial class Customer
{
}
public interface ICustomerMetaData
{
// Apply RequiredAttribute
[Required(ErrorMessage = "Title is required.")]
string Title { get; }
}
Что касается непосредственного использования интерфейса (с использованием Customer: ICustomerMetaData
):
Команда разработчиков не хочет реализовывать эту функцию по двум основным причинам:
• Согласованность с DataAnnotations.Validator
• Согласованность с поведением проверки в ASP.Net MVC
• Сложный сценарий: класс реализует два интерфейса, которые имеют одинаковое свойство, но с конфликтующими атрибутами на них. Какой атрибут будет иметь приоритет?
Хотя MVC автоматически регистрирует метаданные с помощью TypeDescriptor, вам, возможно, придется добавить их самостоятельно:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class Program
{
public static void Main()
{
var customer = new Customer();
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Customer),
typeof(ICustomerMetaData)),
typeof(Customer));
var context = new ValidationContext(customer);
var validationResults = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(
customer, context, validationResults, true);
Console.WriteLine($"is Valid = {isValid}");
customer.Title = "I has Title";
isValid = Validator.TryValidateObject(
customer, context, validationResults, true);
Console.WriteLine($"is Valid = {isValid}");
Console.ReadKey();
}
[MetadataType(typeof(ICustomerMetaData))]
public partial class Customer
{
public string Title { get; set; }
}
public interface ICustomerMetaData
{
// Apply RequiredAttribute
[Required(ErrorMessage = "Title is required.")]
string Title { get; }
}
}
Выход:
Действительный = Ложный
Допустимо = Истина