web-dev-qa-db-fra.com

FluentValidation valide la valeur Enum

J'ai le modèle suivant:

public class ViewDataItem
{
    public string viewName { get; set; }
    public UpdateIndicator updateIndicator { get; set; }
}

Avec l'énumération suivante:

public enum UpdateIndicator
{
    Original,
    Update,
    Delete
}

Et le validateur suivant:

public class ViewValidator : AbstractValidator<ViewDataItem>
{
    public ViewValidator()
    {
        RuleFor(x => x.viewName).NotEmpty().WithMessage("View name must be specified");
        RuleFor(x => x.updateIndicator).SetValidator(new UpdateIndicatorEnumValidator<UpdateIndicator>());
    }
}

public class UpdateIndicatorEnumValidator<T> : PropertyValidator
{
    public UpdateIndicatorEnumValidator() : base("Invalid update indicator") {}

    protected override bool IsValid(PropertyValidatorContext context)
    {
        UpdateIndicator enumVal = (UpdateIndicator)Enum.Parse(typeof(UpdateIndicator), context.PropertyValue.ToString());

        if (!Enum.IsDefined(typeof(UpdateIndicator), enumVal))
          return false;

        return true;
    }
}

Le code est dans une WebAPI qui reçoit des données via JSON, les désérialise en un objet, puis valide, mais pour une raison quelconque, je peux envoyer ce que je veux dans le updateIndicator, tant que je ne mets pas de valeur entière supérieure à l'indice max dans l'énumération (c.-à-d. 1,2 ou 3 fonctionne bien, mais 7 générera une erreur).

Comment puis-je obtenir cela pour valider l'entrée des données que je reçois pour voir si cette valeur est réellement dans l'énumération?

9
JaggenSWE

Le problème vient du fait que le générateur de modèle d'API convertira ce qui est envoyé à une énumération. Si une valeur n'est pas trouvée, elle ne la remplit pas et la valeur par défaut est utilisée (comme elle le serait avec tout autre type de données de propriété non renseigné).

Afin de savoir facilement si la valeur envoyée est une valeur d'énumération valide, vous devez rendre votre propriété nullable. De cette façon, si une valeur ne peut pas être analysée, elle sera définie sur null. Si vous voulez vous assurer que la propriété est définie, demandez simplement à votre validateur de ne pas autoriser les valeurs nulles.

public class ViewDataItem
{
    public string viewName { get; set; }
    public UpdateIndicator? updateIndicator { get; set; }
}

public class ViewValidator : AbstractValidator<ViewDataItem>
{
    public ViewValidator()
    {
        RuleFor(x => x.viewName).NotEmpty().WithMessage("View name must be specified");
        RuleFor(x => x.updateIndicator).NotNull();
    }
}

Sans définir la propriété sur null, votre modèle aura toujours une valeur valide lorsque vous l'aurez. Alternativement, vous pourriez avoir la première valeur de votre énumération comme une valeur fictive, mais ce serait une odeur de code. Une propriété de modèle nulle a beaucoup plus de sens.

Si vous voulez savoir quelle était la valeur réelle qui a été envoyée au point de terminaison API, vous devrez envisager de créer un gestionnaire HTTP , ce qui dépasse le cadre de cette question.

8
krillgar

Essayez le IsInEnum() intégré

RuleFor(x => x.updateIndicator).IsInEnum();

Ceci vérifie si la valeur d'énumération fournie est dans la plage de votre énumération, sinon, la validation échouera:

"'updateIndicator' a une plage de valeurs qui n'inclut pas '7'."

30
Stacked