web-dev-qa-db-ja.com

パラメータが流暢な検証で3つの値の1つであるかどうかを確認する

1つの文字列プロパティを含むクラスがあります:

public class Bla
{
    public string Parameter { get; set; }
}

パラメータがこれらの文字列のいずれかに等しいことを確認するカスタムAbstractValidatorを作成したいと思います。

str1, str2, str3

これが出発点になると思います。

RuleFor(x => x.Parameter).Must(x => x.Equals("str1") || x.Equals("str2") || x.Equals("str3")).WithMessage("Please only use: str1, str2, str3");

しかし、これを連鎖させて、理想的には可能性をハードコーディングせずにエラーメッセージを表示することはできますか?例:

Please only use: str1, str2, str3
14
cs0815

あなたはあなたの条件を含むリストでこれを行うことができます

List<string> conditions = new List{ str1, str2, str3 };
RuleFor(x => x.Parameter)
        .Must(x => conditions.Contains(x))
        .WithMessage("Please only use: " + String.Join(",", conditions);
21
Thomas Ayoub

使用法:

RuleFor(m => m.Job)
    .In("Carpenter", "Welder", "Developer");

出力:

ジョブは次のいずれかの値である必要があります:Carpenter、Welder、またはDeveloper

拡張方法:

public static class ValidatorExtensions
{
    public static IRuleBuilderOptions<T, TProperty> In<T, TProperty>(this IRuleBuilder<T, TProperty> ruleBuilder, params TProperty[] validOptions)
    {
        string formatted;
        if (validOptions == null || validOptions.Length == 0)
        {
            throw new ArgumentException("At least one valid option is expected", nameof(validOptions));
        }
        else if (validOptions.Length == 1)
        {
            formatted = validOptions[0].ToString();
        }
        else
        {
            // format like: option1, option2 or option3
            formatted = $"{string.Join(", ", validOptions.Select(vo => vo.ToString()).ToArray(), 0, validOptions.Length - 1)} or {validOptions.Last()}";
        }

        return ruleBuilder
            .Must(validOptions.Contains)
            .WithMessage($"{{PropertyName}} must be one of these values: {formatted}");
    }
}
9
Drew Delano

上記のThomasのコードスニペットに同意します。私が時々採用したい別のアプローチ:検証がドメインの概念として意味がある場合は、次のようなメソッドに分割できます。

RuleFor(x=>x.Parameter).Must(BeAValidParameter).WithMessage("Your parameter must be a valid parameter.");

    private static bool BeAValidParameter(string arg)
    {
        return arg.Equals("str1") || arg.Equals("str2") || arg.Equals("str3");
    }

私はこれをBeAValidZipCodeBeAValidPhoneNumber、または1つのビジネスコンセプトを表現する複雑なロジックのようなものによく使用します。標準の検証の概念と組み合わせて使用​​できます(たとえば、すべての検証を1つのメソッドに配置しようとしないでください)。

3
SeanKilleen