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
あなたはあなたの条件を含むリストでこれを行うことができます
List<string> conditions = new List{ str1, str2, str3 };
RuleFor(x => x.Parameter)
.Must(x => conditions.Contains(x))
.WithMessage("Please only use: " + String.Join(",", conditions);
使用法:
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}");
}
}
上記の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");
}
私はこれをBeAValidZipCode
、BeAValidPhoneNumber
、または1つのビジネスコンセプトを表現する複雑なロジックのようなものによく使用します。標準の検証の概念と組み合わせて使用できます(たとえば、すべての検証を1つのメソッドに配置しようとしないでください)。