82

次のビューモデル定義があります

public class AccessRequestViewModel
{
    public Request Request { get; private set; }
    public SelectList Buildings { get; private set; }
    public List<Person> Persons { get; private set; }
}

したがって、私のアプリケーションでは、アクセス要求に対して少なくとも 1 人が必要です。検証にはどのようなアプローチを使用できますか? この検証をコントローラーで行うのは簡単でありたくありません。唯一の選択肢はカスタム検証属性ですか?

編集:現在、この検証を FluentValidation で実行しています (素敵なライブラリ!)

RuleFor(vm => vm.Persons)
                .Must((vm, person) => person.Count > 0)
                .WithMessage("At least one person is required");
4

7 に答える 7

179

データ注釈を使用して検証を実行している場合は、カスタム属性が必要になる場合があります。

public class EnsureOneElementAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        var list = value as IList;
        if (list != null)
        {
            return list.Count > 0;
        }
        return false;
    }
}

その後:

[EnsureOneElement(ErrorMessage = "At least a person is required")]
public List<Person> Persons { get; private set; }

またはそれをより一般的にするために:

public class EnsureMinimumElementsAttribute : ValidationAttribute
{
    private readonly int _minElements;
    public EnsureMinimumElementsAttribute(int minElements)
    {
        _minElements = minElements;
    }

    public override bool IsValid(object value)
    {
        var list = value as IList;
        if (list != null)
        {
            return list.Count >= _minElements;
        }
        return false;
    }
}

その後:

[EnsureMinimumElements(1, ErrorMessage = "At least a person is required")]
public List<Person> Persons { get; private set; }

個人的には、データ注釈の代わりにFluentValidation.NETを使用して検証を実行します。これは、宣言型ではなく命令型の検証ロジックを好むためです。よりパワフルになったと思います。したがって、私の検証ルールは次のようになります。

RuleFor(x => x.Persons)
    .Must(x => x.Count > 0)
    .WithMessage("At least a person is required");
于 2011-02-28T19:44:59.167 に答える
9

Darinの答えは良いですが、以下のバージョンでは自動的に有用なエラーメッセージが表示されます.

public class MinimumElementsAttribute : ValidationAttribute
{
    private readonly int minElements;

    public MinimumElementsAttribute(int minElements)
    {
        this.minElements = minElements;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var list = value as IList;

        var result = list?.Count >= minElements;

        return result
            ? ValidationResult.Success
            : new ValidationResult($"{validationContext.DisplayName} requires at least {minElements} element" + (minElements > 1 ? "s" : string.Empty));
    }
}

使用法:

[MinimumElements(1)]
public List<Customer> Customers {get;set}

[MinimumElements(2)]
public List<Address> Addresses {get;set}

エラーメッセージ:

  • 顧客は少なくとも 1 つの要素を必要としています
  • 住所には少なくとも 2 つの要素が必要です
于 2018-01-16T09:34:36.333 に答える
2

ここでは、カスタム検証属性を作成してプロパティを装飾するか、ViewModelにインターフェイス(メソッドIValidatableObjectを定義する)を実装させるかの2つの選択肢があります。Validate

お役に立てれば :)

于 2011-02-28T19:52:47.437 に答える
0

1 つの方法は、プライベート コンストラクターと静的メソッドを使用してオブジェクトのインスタンスを返すことです。

public class AccessRequestViewModel
{
    private AccessRequesetViewModel() { };

    public static GetAccessRequestViewModel (List<Person> persons)
    {
            return new AccessRequestViewModel()
            {
                Persons = persons,
            };
    }

    public Request Request { get; private set; }
    public SelectList Buildings { get; private set; }
    public List<Person> Persons { get; private set; }
}

常にファクトリを使用して ViewModel をインスタンス化することで、常に人が存在することを保証できます。

これはおそらくあなたが望むものには理想的ではありませんが、うまくいくでしょう。

于 2011-02-28T19:45:09.190 に答える