web-dev-qa-db-ja.com

FluentValidation検証列挙値

私は次のモデルを持っています:

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

次の列挙型の場合:

public enum UpdateIndicator
{
    Original,
    Update,
    Delete
}

そして次のバリデータ:

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

コードは、JSONを介してデータを受信し、それをオブジェクトにデシリアライズして検証するWebAPIにありますが、何らかの理由で、updateIndicatorに入れない限り、何でも送信できます列挙型の最大インデックスより大きい整数値(つまり、1、2または3は問題なく動作しますが、7はエラーを生成します)。

これを取得して、受け取ったデータの入力を検証し、その値が実際に列挙型にあるかどうかを確認するにはどうすればよいですか?

9
JaggenSWE

問題は、APIモデルビルダーが送信されたものを列挙型に変換するという事実から発生します。値が見つからない場合、その値は設定されず、デフォルト値が使用されます(設定されていない他のプロパティデータタイプの場合と同様)。

送信された値が有効な列挙値であるかどうかを簡単に確認するには、プロパティをnullにできるようにする必要があります。このようにして、値を解析できない場合、値はnullに設定されます。プロパティが設定されていることを確認する場合は、バリデーターでnull値を許可しないようにします。

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

プロパティをnullに設定しないと、モデルは常に有効な値になります。または、列挙型の最初の値をダミー値にすることもできますが、それはコードのにおいになります。 nullモデルプロパティは、はるかに理にかなっています。

APIエンドポイントに送信された実際の値が何であるかを知りたい場合は、この質問の範囲を超える HTTP Handler の作成を確認する必要があります。

8
krillgar

組み込みのIsInEnum()を試す

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

これは、提供された列挙値が列挙の範囲内にあるかどうかをチェックし、そうでない場合、検証は失敗します。

「 'updateIndicator'には '7'を含まない値の範囲があります。」

30
Stacked