it-swarm.com.de

ASP.NET Core - Überprüfung des benutzerdefinierten Modells

Wenn wir in MVC ein Modell für eine Aktion bereitstellen, führen wir folgende Schritte aus, um das Modell anhand der Datenanmerkungen dieses Modells zu überprüfen:

if (ModelState.IsValid)

Wenn wir eine Eigenschaft als [Erforderlich] markieren, überprüft ModelState.IsValid diese Eigenschaft, wenn sie einen Wert enthält oder nicht.

Meine Frage: Wie kann ich einen benutzerdefinierten Prüfer manuell erstellen und ausführen?

P.S. Ich spreche nur vom Backend-Validator.

8
user2818430

In .NET Core können Sie einfach eine Klasse erstellen, die von ValidationAttribute erbt. Sie finden alle Details in ASP.NET Core MVC Docs .

Hier ist das Beispiel direkt aus den Dokumenten:

public class ClassicMovieAttribute : ValidationAttribute
{
    private int _year;

    public ClassicMovieAttribute(int Year)
    {
        _year = Year;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        Movie movie = (Movie)validationContext.ObjectInstance;

        if (movie.Genre == Genre.Classic && movie.ReleaseDate.Year > _year)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }
}

Ich habe das Beispiel angepasst, um die clientseitige Validierung auszuschließen, wie in Ihrer Frage gefordert.

Um dieses neue Attribut (wieder aus den Dokumenten) zu verwenden, müssen Sie es dem entsprechenden Feld hinzufügen:

[ClassicMovie(1960)]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

Hier ist ein weiteres, einfacheres Beispiel, um sicherzustellen, dass ein Wert true ist:

public class EnforceTrueAttribute : ValidationAttribute
{
    public EnforceTrueAttribute()
        : base("The {0} field must be true.") { }

    public override bool IsValid(object value) =>
        value is bool valueAsBool && valueAsBool;
}

Dies wird auf die gleiche Weise angewendet:

[EnforceTrue]
public bool ThisShouldBeTrue { get; set; }
14
Kirk Larkin

Um ein benutzerdefiniertes Validierungsattribut in .Net Core zu erstellen, müssen Sie von IModelValidator erben und die Validate-Methode implementieren.

Benutzerdefinierter Validator

public class ValidUrlAttribute : Attribute, IModelValidator
{
    public string ErrorMessage { get; set; }

    public IEnumerable<ModelValidationResult> Validate(ModelValidationContext context)
    {
        var url = context.Model as string;
        if (url != null && Uri.IsWellFormedUriString(url, UriKind.Absolute))
        {
            return Enumerable.Empty<ModelValidationResult>();
        }

        return new List<ModelValidationResult>
        {
            new ModelValidationResult(context.ModalMetadata.PropertyName, ErrorMessage)
        };
    }
}

Das Model

public class Product
{
    public int ProductId { get; set; }

    [Required]
    public string ProductName { get; set; }

    [Required]
    [ValidUrl]
    public string ProductThumbnailUrl { get; set; }
}

Wird dieser Ansatz die Möglichkeit bieten, mit der Eigenschaft "ModelState.IsValid" in der Controller-Aktionsmethode zu arbeiten?

Ja! Das ModalState-Objekt gibt die Fehler korrekt wieder.

Kann dieser Ansatz auf die Modellklasse angewendet werden? Oder es kann nur mit Eigenschaften von Modellklassen verwendet werden?

Ich weiß nicht, ob das auf Klassenebene angewendet werden kann. Ich weiß, dass Sie die Informationen über die Klasse von ModalValidationContext erhalten können:

  • context.Modal: gibt den Eigenschaftswert zurück, der überprüft werden soll
  • context.Container: gibt das Objekt zurück, das die Eigenschaft enthält
  • context.ActionContext: liefert Kontextdaten und beschreibt die Aktionsmethode, die die Anforderung verarbeitet
  • context.ModelMetadata: beschreibt die zu validierende Modellklasse im Detail

Anmerkungen:

Dieses Validierungsattribut funktioniert nicht mit der Client-Validierung, wie in OP gefordert.

6
David Liang

Ich habe dieselbe Lösung zum Überprüfen von NULLs verwendet, aber es funktioniert nicht für mich.

using System.ComponentModel.DataAnnotations;

/// <summary>
/// Defines the <see cref="NullCheckAttribute" />
/// </summary>
public class NullCheckAttribute : ValidationAttribute
{
    public NullCheckAttribute()
    : base("The {0} field should not be null.") { }

    public override bool IsValid(object value)
    {
        return value != null;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null)
        {
            return new ValidationResult("The value should not be null");
        }

        return ValidationResult.Success;
    }
}
0
Muni Chittem