Расширение валидаторов ASP.NET - PullRequest
9 голосов
/ 01 августа 2010

Я хочу расширить валидаторы 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, в идеале я хотел бы предоставить эту функциональность для всех валидаторов, но я не могу найти способ сделать это без копирования приведенного выше кода в аналогичный класс для каждого отдельного типа валидатора Я хочу предоставить эту функциональность, поэтому, если возникнут какие-либо проблемы, мне придется вернуться и изменить этот код для каждого типа валидатора отдельно.

Есть ли способ, которым я могу "централизовать" этот код и легко использовать его в валидаторах без необходимости писать целые валидаторы с нуля просто для того, чтобы я мог изменить класс, который они наследуют, в дальнейшем.

Приветствия

Ответы [ 4 ]

1 голос
/ 01 августа 2010

Вы можете переопределить метод Validate в своей базе страниц.Чтобы добавить информацию о проверочной зависимости на страницу, вы можете реализовать не визуализированный элемент управления:

<my:ValidationDependency TargetControl="RegExp1" Dependency="Required1" />
0 голосов
/ 03 августа 2010

Возможно, вы захотите заглянуть в 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 / другой механизм хранения.

0 голосов
/ 01 августа 2010

Я смотрю на расширители управления, которые, кажется, могут быть многообещающими, но я не могу найти много примеров того, как что-то делать, кроме AJAX.

0 голосов
/ 01 августа 2010

вы можете иметь свойство ValidationControlToDependOn типа List и добавлять валидаторы в список. Таким образом, мы можем предположить, что валидатор, добавленный позже, зависит от валидатора, добавленного перед ним.

значит твой protected override bool EvaluateIsValid()

немного изменится

foreach(IValidator validator in ValidationControlToDependOn)
{
return !validator.IsValid;

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...