9 Stimmen

Erweiterung der ASP.NET-Validierer

Ich möchte die asp.net-Validatoren so erweitern, dass ich einen Validator von einem anderen abhängig machen kann. Die Situation, die ich habe, ist, dass wir ein Datum in einem Textfeld zu validieren haben. Normalerweise würde ich nur eine Kombination aus einem RequiredFieldValidator (um sicherzustellen, dass das Datum angegeben wird), einem CompareValidator (um sicherzustellen, dass das Datum ein Datum ist) und schließlich einem RangeValidator (um sicherzustellen, dass das Datum innerhalb der erforderlichen Grenze liegt) verwenden.

Das Problem dabei ist, dass die Prüfer nicht voneinander abhängen, so dass der Benutzer möglicherweise alle drei Meldungen für jeden Prüfer auf einmal sehen würde, obwohl wir eigentlich nur die relevanteste Meldung sehen wollen, d. h. wenn er "abc" in das Textfeld für das Datum eingegeben hat, wäre es nicht angemessen, ihm die Meldung zu zeigen, dass das Datum nicht im gültigen Bereich liegt (obwohl das technisch gesehen vermutlich stimmt).

Um diese Art von Funktionalität bereitzustellen, verwenden wir derzeit einen CustomValidator und setzen alle drei Validierungen in den Server-Validate-Event-Handler und ändern die Fehlermeldung programmatisch, je nachdem, welche Validierung fehlgeschlagen ist.

Ich möchte dies ein bisschen mehr zu standardisieren, wie es ziemlich viel in dieser Anwendung geschieht, ich denke, wenn ich die Validatoren voneinander abhängig machen kann dies das Problem lösen und auch uns erlauben, die Client-Seite Validierung zu verwenden, anstatt mit einem Postback speziell die benutzerdefinierte Validierung zu behandeln.

Die Idee ist, dass, wenn ein Prüfer von einem anderen abhängig ist und dieser "Master" gültig ist, der abhängige Prüfer seine normale Prüfung durchführt (EvaluateIsValid()), andernfalls, wenn der Master-Prüfer nicht gültig ist, werden die anderen abhängigen Prüfer gültig sein.

Ich habe die folgende Lösung gefunden, indem ich von den verschiedenen Validator-Steuerelementen geerbt habe, die bereits im Framework enthalten sind.

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();
    }

Derzeit habe ich nur codiert es für die RequiredFieldValidator, idealerweise möchte ich diese Funktionalität für alle Validatoren bieten, aber ich kann nicht sehen, eine Möglichkeit, dies zu tun, ohne Kopieren der oben genannten Code in eine ähnliche Klasse für jeden einzelnen Typ von Validator ich diese Funktionalität für so bereitstellen möchten, wenn es irgendwelche Probleme gibt, ich werde zurück zu gehen und ändern Sie diesen Code auf jedem Validator-Typ einzeln.

Gibt es eine Möglichkeit, wie ich diesen Code "zentralisieren" und ihn leicht in den Validatoren verwenden kann, ohne die gesamten Validatoren von Grund auf neu schreiben zu müssen, nur damit ich die Klasse, von der sie erben, im weiteren Verlauf ändern kann.

Zum Wohl,

1voto

onof Punkte 16911

Sie könnten die Validate-Methode in der Basis Ihrer Seite überschreiben. Um die Informationen zur Validierungsabhängigkeit auf der Seite hinzuzufügen, können Sie ein nicht gerendertes Steuerelement implementieren:

<my:ValidationDependency TargetControl="RegExp1" Dependency="Required1" />

0voto

ajay_whiz Punkte 16775

Können Sie ValidationControlToDependOn Eigenschaft vom Typ Liste und fügen Sie die Prüfer in die Liste ein. Wir können also davon ausgehen, dass der später hinzugefügte Prüfer von dem zuvor hinzugefügten Prüfer abhängt.

damit Ihr protected override bool EvaluateIsValid()

wird sich etwas ändern

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

}

0voto

Daniel Powell Punkte 7972

Ich schaue in Control Extenders, die wie es scheint, könnte vielversprechend sein, aber ich kann nicht finden, viele Beispiele für etwas tun, aber AJAX Zeug mit ihm.

0voto

Sam Punkte 1464

Vielleicht möchten Sie sich einen WebControlAdapter ansehen.

Grundsätzlich können Sie bestimmte Methoden von Webcontrols überschreiben (bedingt für einige Browser, wenn nötig, aber hier kann für alle sein).

In Ihrem Fall sollten Sie die EvaluateIsValid-Methode überschreiben und prüfen, ob das Steuerelement von einem "übergeordneten" Prüfer abhängig ist.

Ein Beispiel ist ein TextBox-Adapter, den wir kürzlich erstellt haben, um dem Steuerelement ein Attribut "maxlength" zuzuweisen.

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

Um ihn zu verwenden, erstellen Sie einfach eine .browser-Datei in Ihrem App_Browsers-Verzeichnis und richten den Adapter dort ein:

<browsers>
    <browser refID="Default">
        <controlAdapters>
            <adapter controlType="System.Web.UI.WebControls.TextBox"
               adapterType="TextBoxAdapter" />
        </controlAdapters>
    </browser>
</browsers>

Die einzige Komplikation, die in Ihrem Fall noch bleibt, ist die Frage, wie der abhängige Validator gespeichert werden kann, damit EvaluateIsValid Zugriff auf dieses Verzeichnis hat. Sie könnten ein nicht gerendertes Steuerelement in Betracht ziehen, wie Onof vorgeschlagen hat, oder Viewstate/Cookie/einen anderen Speichermechanismus.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X