Validation Framework в.NET, который может редактировать поля
Исходя из моего опыта, многие платформы валидации в.NET позволяют проверять одно поле за раз, например, для обеспечения того, чтобы поле представляло собой почтовый индекс или адрес электронной почты. Я обычно называю это внутриполевыми правками.
В моем проекте нам часто приходится вносить изменения между полями. Например, если у вас есть такой класс:
public class Range
{
public int Min { get; set; }
public int Max { get; set; }
}
Вы можете убедиться, что Макс больше, чем Мин. Вы также можете выполнить некоторую проверку для внешнего объекта. Например, если у вас есть такой класс:
public class Person
{
public string PostalCode { get; set; }
}
и по какой-либо причине вы хотите убедиться, что Почтовый индекс существует в базе данных или в предоставленном вам файле. У меня есть более сложные примеры, например, когда пользователь предоставляет словарь данных, и вы хотите проверить свой объект по этому словарю данных.
Мой вопрос: можем ли мы использовать любую из существующих платформ валидации (TNValidate, NHibernate Validator) для.NET или нам нужно использовать механизм правил или как? Как вы, люди в реальном мире, справляетесь с этой ситуацией?:-)
2 ответа
Я хорошо знаю только одну платформу валидации: блок приложения для проверки корпоративных библиотек, или для краткости VAB. Я отвечу на ваши вопросы из контекста VAB.
Первый вопрос: Можете ли вы сделать проверку состояния (между полями) в VAB?
Да, ты можешь. Есть несколько способов сделать это. Вы можете выбрать механизм самопроверки следующим образом:
[HasSelfValidation]
public class Range
{
public int Min { get; set; }
public int Max { get; set; }
[SelfValidation]
public void ValidateRange(ValidationResults results)
{
if (this.Max < this.Min)
{
results.AddResult(
new ValidationResult("Max less than min", this, "", "", null));
}
}
}
Я должен сказать, что лично мне не нравятся проверки этого типа, особенно при проверке сущностей моего домена, потому что я хотел бы отделить свои проверки от логики проверки (и не допускать, чтобы моя логика домена содержала ссылки на какие-либо рамки проверки). Однако им требуется значительно меньше кода, чем альтернативе, которая пишет собственный класс валидатора. Вот пример:
[ConfigurationElementType(typeof(CustomValidatorData))]
public sealed class RangeValidator : Validator
{
public RangeValidator(NameValueCollection attributes)
: base(string.Empty, string.Empty) { }
protected override string DefaultMessageTemplate
{
get { throw new NotImplementedException(); }
}
protected override void DoValidate(object objectToValidate,
object currentTarget, string key, ValidationResults results)
{
Range range = (Range)currentTarget;
if (range.Max < range.Min)
{
this.LogValidationResult(results,
"Max less than min", currentTarget, key);
}
}
}
После написания этого класса вы можете подключить этот класс в своем файле конфигурации проверки следующим образом:
<validation>
<type name="Range" defaultRuleset="Default" assemblyName="[Range Assembly]">
<ruleset name="Default">
<validator type="[Namespace].RangeValidator, [Validator Assembly]"
name="Range Validator" />
</ruleset>
</type>
</validation>
Второй вопрос: как проводить сложные проверки с возможным взаимодействием с базой данных (с VAB).
Примеры, которые я привожу для первого вопроса, также пригодны для этого. Вы можете использовать те же методы: самопроверка и пользовательский валидатор. Ваш сценарий, в котором вы хотите проверить значение в базе данных, на самом деле прост, потому что валидность вашего объекта не зависит от его контекста. Вы можете просто проверить состояние объекта по базе данных. Это становится более сложным, когда контекст, в котором живет объект, становится важным (но это возможно с VAB). Представьте себе, например, что вы хотите написать валидацию, которая гарантирует, что у каждого клиента в данный момент времени не более двух отгруженных заказов. Это не только означает, что вы должны проверить базу данных, но, возможно, новые заказы, которые добавляются или заказы удаляются в том же контексте. Эта проблема не относится к VAB, у вас будут одинаковые проблемы с каждой выбранной вами средой. Я написал статью, в которой описываются сложности, с которыми мы сталкиваемся в этих ситуациях (чтение и дрожь).
Третий вопрос: как вы, люди в реальном мире, справляетесь с этой ситуацией?
Я делаю эти типы проверки с VAB в производственном коде. Это прекрасно работает, но VAB не очень прост в освоении. Тем не менее, мне нравится то, что мы можем сделать с VAB, и это будет только лучше, когда выйдет v5.0. Если вы хотите изучить его, начните с чтения документа ValidationHOL.pdf, который вы можете найти в загрузке практических занятий.
Надеюсь, это поможет.
Я создаю пользовательские элементы управления проверкой, когда мне нужно что-то, что не входит в комплект поставки. Приятно, что эти пользовательские валидаторы можно использовать повторно и они могут работать с несколькими полями. Вот пример, который я опубликовал в CodeProject валидатора AtLeastOneOf, который позволяет вам требовать, чтобы хотя бы одно поле в группе имело значение:
http://www.codeproject.com/KB/validation/AtLeastOneOfValidator.aspx
Код, включенный в загрузку, должен работать как простой пример того, как вы можете это сделать. Недостатком является то, что средства проверки, включенные в ASP.Net, не всегда хорошо работают с asp.net-ajax.