Я использую xVal в своем приложении ASP.NET MVC, что в целом отлично. После сообщения в блоге Стива Сандерсона, я создал DataAnnotationsValidationRunner для проверки атрибутов объектов на стороне сервера. Это отлично подходит для простого класса. например Человек:
public static class DataAnnotationsValidationRunner
{
public static IEnumerable<ErrorInfo> GetErrors(object o)
{
return from prop in TypeDescriptor.GetProperties(o).Cast<PropertyDescriptor>()
from attribute in prop.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(prop.GetValue(o))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), o);
}
}
public class Person
{
[Required(ErrorMessage="Please enter your first name")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter your last name")]
public string LastName { get; set; }
}
Однако, если я добавлю этому человеку свойство Address и помечу класс Address атрибутами DataAnnotation, они не будут проверены. например
public class Person
{
[Required(ErrorMessage="Please enter your first name")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter your last name")]
public string LastName { get; set; }
public Address Address { get; set; }
}
public class Address
{
[Required(ErrorMessage="Please enter a street address")]
public string Street { get; set; }
public string StreetLine2 { get; set; }
[Required(ErrorMessage = "Please enter your city")]
public string City { get; set; }
[Required(ErrorMessage = "Please enter your state")]
public string State { get; set; }
[Required(ErrorMessage = "Please enter your zip code")]
public string Zip { get; set; }
public string Country { get; set; }
}
Одна из проблем заключается в том, что DataAnnotationValidationRunner не просматривает сложные дочерние свойства. Кроме того, если эти ошибки добавляются в коллекцию ошибок, они все равно должны получить правильный префикс при добавлении в состояние модели. Например. Ошибки Person добавляются так:
catch (RulesException ex)
{
ex.AddModelStateErrors(ModelState, "person");
}
Я думаю, что исключения из правил адресов должны быть помечены префиксом "person.address". Есть ли поддерживаемый способ обработки проверки дочернего объекта с помощью xVal, или создание плоского объекта передачи данных будет единственным решением?