У MVC есть крючок, чтобы предоставить свой собственный ModelValidatorProvider. По умолчанию MVC 2 использует подкласс класса ModelValidatorProvider, называемый DataAnnotationsModelValidatorProvider, который может использовать атрибуты System.DataAnnotations.ComponentModel.ValidationAttribute для проверки.
DataAnnotationsModelValidatorProvider использует отражение, чтобы найти все атрибуты ValidationAttributes и просто петли через коллекцию для проверки ваших моделей. Все, что вам нужно сделать, это переопределить метод GetValidators и ввести собственные атрибуты из того источника, который вы выберете. Я использую эту технику для проверки условных условий, свойства с атрибутом DataType.Email всегда передаются через регулярное выражение и используют этот метод для извлечения информации из базы данных, чтобы применить более ограничительные проверки для пользователей, не имеющих полномочий.
Следующий пример просто говорит «всегда делать какие-либо свойства FirstName необходимые»:
public class CustomMetadataValidationProvider : DataAnnotationsModelValidatorProvider
{
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
//go to db if you want
//var repository = ((MyBaseController) context.Controller).RepositorySomething;
//find user if you need it
var user = context.HttpContext.User;
if (!string.IsNullOrWhiteSpace(metadata.PropertyName) && metadata.PropertyName == "FirstName")
attributes = new List<Attribute>() {new RequiredAttribute()};
return base.GetValidators(metadata, context, attributes);
}
}
Все, что вам нужно сделать, это зарегистрировать поставщика в файле Global.asax.cs:
protected void Application_Start()
{
ModelValidatorProviders.Providers.Add(new CustomMetadataValidationProvider());
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
конечный результат:
ш Ith этой модели:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Birthday { get; set; }
}
этот замечательный материал jfar! ;) Я думаю, вы спасли меня глубоким погружением в VAB. – mare
Одна из проблем с примером кода в этом ответе - это атрибуты, которые можно обрабатывать дважды: один раз ваш подкласс «DataAnnotationsModelValidatorProvider» и один раз уже существующим. Это может привести к ошибкам. Я думаю, что лучше только передавать атрибуты, которые вы добавляете в вызов 'base.GetValidators', чтобы избежать этого. – Sam
Кроме того, в ASP.NET MVC 4 (и, возможно, другие), 'base.GetValidators' автоматически добавляет' RequiredAttribute', когда 'metadata.IsRequired' является' true'. Один из способов обойти это - установить 'metadata.IsRequired'' false' перед вызовом 'base.GetValidators'. После вызова вы можете вернуть его к исходному значению. – Sam