Я хочу расширить блоки проверки допустимости asp.net, таким образом, что я могу сделать один блок проверки допустимости зависящим от другого. Ситуация, которую я имею, состоит в том, что мы должны проверить дату в текстовом поле. Обычно я просто использовал бы комбинацию RequiredFieldValidator (чтобы гарантировать, что дата обеспечивается), CompareValidator (чтобы гарантировать, что дата является датой) и наконец RangeValidator (чтобы гарантировать, что дата в необходимом пределе).
Проблема с этим состоит в том, что блоки проверки допустимости не зависят друг от друга, таким образом, в результате пользователь видел бы возможно все три сообщения сразу для каждого блока проверки допустимости, когда действительно все, что мы хотим, чтобы они видели, является самым соответствующим сообщением, т.е. если бы они ввели "abc" в текстовое поле даты, то не было бы уместно показать им сообщение, говоря, что дата не была в допустимом диапазоне (даже при том, что технически я предполагаю, что это верно).
В настоящее время для обеспечения этого вида функциональности мы используем CustomValidator и просто помещаем все три проверки в сервере, проверяют обработчик событий и изменяют сообщение об ошибке программно в зависимости от того, что привела к сбою проверка.
Я хотел бы стандартизировать это немного больше, как это происходит вполне немного в этом приложении, я фигурирую, могу ли я сделать блоки проверки допустимости зависящими друг от друга, это решит проблему и также позволит нам использовать клиентскую проверку вместо того, чтобы иметь необходимость сделать обратную передачу особенно для обработки пользовательской проверки.
Идея состоит в том, что, если один блок проверки допустимости зависит от другого, если то "ведущее устройство" допустимо затем, зависевший выполнит свою нормальную проверку (EvaluateIsValid ()) иначе, если основной блок проверки допустимости не будет допустим затем, то другие зависимые блоки проверки допустимости будут допустимы.
Я предложил следующее решение путем наследования различным элементам управления проверки правильности, которые уже были обеспечены в платформе.
public class RequiredFieldDependentValidator : RequiredFieldValidator
{
[Description("The validation control to depend on for determining if validation should occur")]
public string ValidationControlToDependOn
{
get
{
object obj = ViewState["ValidationControlToDependOn"];
if (obj != null) return (string) obj;
return null;
}
set
{
Control control = FindControl(value);
if (control is IValidator)
ViewState["ValidationControlToDependOn"] = value;
else
throw new HttpException("ValidationControlToDependOn is not a validation control");
}
}
protected override bool EvaluateIsValid()
{
IValidator validationControlToDependOn = FindControl(ValidationControlToDependOn) as IValidator;
if(validationControlToDependOn != null)
{
return !validationControlToDependOn.IsValid || base.EvaluateIsValid();
}
return base.EvaluateIsValid();
}
В настоящее время я только что кодировал его для RequiredFieldValidator, идеально я хотел бы обеспечить эту функциональность для всех блоков проверки допустимости, но я не вижу способ сделать это, не копируя вышеупомянутый код в подобный класс для каждого отдельного типа блока проверки допустимости, для которого я хочу обеспечить эту функциональность таким образом, если существуют какие-либо проблемы, я оказываюсь перед необходимостью возвращаться и изменять этот код каждого типа блока проверки допустимости индивидуально.
Есть ли способ, которым я могу "централизовать" этот код и использовать его легко в блоках проверки допустимости, не имея необходимость писать все блоки проверки допустимости с нуля именно так, я могу изменить класс, которому они наследовались далее по линии.
Удачи,
Вы можете изучить WebControlAdapter.
В основном позволяет вам переопределить определенные методы веб-управления (условно для некоторых браузеров, если необходимо, но здесь может быть для всех).
В вашем случае вам нужно переопределить метод EvaluateIsValid и проверить, имеет ли элемент управления какую-либо зависимость от «родительского» валидатора.
Например, адаптер TextBox, который мы недавно создали для рендеринга атрибута maxlength для элемента управления.
Public Class TextBoxAdapter
Inherits WebControlAdapter
Private ReadOnly Property TextBoxControl() As TextBox
Get
Return DirectCast(MyBase.Control, TextBox)
End Get
End Property
Protected Overrides Sub RenderBeginTag(ByVal writer As System.Web.UI.HtmlTextWriter)
If TextBoxControl.TextMode = TextBoxMode.MultiLine AndAlso TextBoxControl.MaxLength > 0 Then
writer.AddAttribute("maxlength", TextBoxControl.MaxLength.ToString)
End If
MyBase.RenderBeginTag(writer)
End Sub
End Class
Чтобы использовать его, просто создайте файл .browser в вашем каталоге App_Browsers и настройте там адаптер:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.TextBox"
adapterType="TextBoxAdapter" />
</controlAdapters>
</browser>
</browsers>
Единственная сложность, которая все еще остается в вашем случае, - это как сохранить зависимый валидатор, чтобы EvaluateIsValid имел доступ в этот каталог. Вы можете рассмотреть необработанный элемент управления, такой как предложенный Onof, или Viewstate / Cookie / другой механизм хранения.
вы можете иметь свойство ValidationControlToDependOn
типа List и добавлять валидаторы в список. Таким образом, мы можем предположить, что валидатор, добавленный позже, зависит от валидатора, добавленного до него.
поэтому ваша protected override bool EvaluateIsValid()
несколько изменится
foreach(IValidator validator in ValidationControlToDependOn)
{
return !validator.IsValid;
}
Я изучаю расширители элементов управления, которые кажутся многообещающими, но я не могу найти много примеров того, как с ними делать что-либо, кроме AJAX.
Вы можете переопределить метод Validate в своей базе страницы. Чтобы добавить информацию о проверочной зависимости на страницу, вы можете реализовать необработанный элемент управления:
<my:ValidationDependency TargetControl="RegExp1" Dependency="Required1" />