2017-07-10 1 views
1

je le modèle suivant:FluentValidation validate valeur Enum

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

Avec l'ENUM 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 un WebAPI qui reçoit des données via JSON, les désérialise sur un objet puis les valide, mais pour une raison quelconque je peux envoyer ce que je veux dans le updateIndicator, tant que je ne mets pas une valeur entière plus grande que l'index max dans l'énumération (c'est-à-dire que 1, 2 ou 3 fonctionne bien, mais 7 générera une erreur).

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

+0

Vous essayez de voir si 'viewName' est une valeur de texte dans' UpdateIndicator'? – krillgar

+0

J'essaie de voir si la valeur de texte envoyée en tant que "updateIndicator" existe réellement dans le Enum UpdateIndicator. Si quelqu'un envoie des "bananes", il devrait renvoyer une erreur, mais si quelqu'un envoie "Original" (qui existe dans l'énumération), il devrait juste valider. – JaggenSWE

+1

Cela n'arrivera pas. Essayez d'appeler votre point de terminaison de Postman ou Fiddler avec une valeur non valide, et voyez ce qui se passe. Il vous donnera la valeur par défaut de l'enum (première valeur). Si vous voulez vous prémunir contre cela, vous pouvez rendre la propriété nullable, mais votre validation ne permet pas les valeurs nulles. – krillgar

Répondre

2

Le problème provient du fait que le constructeur de modèle API va convertir 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 pour tout autre type de données de propriété non renseigné).

Afin de déterminer facilement si la valeur envoyée est une valeur enum 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 à votre validateur de ne pas autoriser de valeurs NULL. Sans définir la propriété à null, votre modèle aura toujours une valeur valide lorsque vous l'avez. Alternativement, vous pourriez avoir la première valeur de votre énumération soit une valeur fictive, mais ce serait une odeur de code. Une propriété de modèle nulle a beaucoup plus de sens.

Si vous souhaitez connaître la valeur réelle qui a été envoyée au point de terminaison API, vous devez créer un HTTP Handler, ce qui dépasse le cadre de cette question.

6

Essayez le intégré IsInEnum()

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

Ce vérifie si la condition valeur ENUM est comprise dans la plage de votre ENUM, sinon, la validation échouera:

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