0

私はしばらくの間、モデルの検証をどのように行っているかをリファクタリングするのに苦労してきました。私のアプリケーションはすべてASP.NETMVC2(.Net 3.5フレームワーク)です。私はこの主題に関連する質問を読みましたが、それらは私が尋ねているものとまったく同じではありません。

現在、ページの検証のために、私は通常、if/elseステートメントの寄せ集めに固執しました。問題は、フィールドAが特定の値である場合、フィールドBが検証されることがありますが、フィールドAにも独自の検証があることです。場合によっては、関係する役割があり、これにより、ユーザーの役割によっても検証が行われる場合があります(つまり、役割xのユーザーが変更できないフィールドを検証しないでください)。

私の質問はこれに要約されます:

1)読みやすい方法で検証を処理するにはどうすればよいですか?DataAnnotationsを見てきましたが、十分ではありません。データ注釈はフィールドの値の検証を処理しますが、実行する必要のある検証は、フィールドの値とオブジェクトの他のプロパティの値の両方に依存します。

2)検証フレームワークをASP.NET MVC 2と統合するにはどうすればよいですか?

現在検証を行っている方法について私が本当に嫌いなのは、モデルエラーを追加すると、そのプロパティのキーをハードコーディングしていることです。それはかなり悪いです。それでも、htmlヘルパーによって作成されたhtmlフィールドと一致するように、上記のプロパティのキーを取得する方法がわかりません。

たとえば、私のビューでは、エディタテンプレートを使用して、顧客オブジェクトのフィールドを表示しています。

   <%= Html.EditorFor(m => m.CustomerInfo) %>

生成されたhtmlの一部は、FirstNameのフィールドを作成します。

<input id="CustomerInfo_FirstName" name="CustomerInfo.FirstName" style="width:330px;" type="text" value="John" />

フレームワークが必要なCSSでフィールドを強調表示するために、私はこの検証を次のように強制しています。

//Ignore that this can be done with DataAnnotations. This is just a simple example.   
if (String.IsnullOrEmpty(customerInfo.FirstName) )
{
    ModelState.AddModelError("CustomerInfo.FirstName",
    "First Name is required.");
}

これが私が大きな問題だと思っていることです。ページ上のフィールドの名前を知る良い方法がありません。のパターンを取るようです

 <objectname>.<propertyname>

、しかし私は本当にもっと信頼できるものが欲しいです。

オブジェクト名を取得するには、ModelBindingContextクラスからオブジェクト名を取得できると思いますが、コントローラーの内部からこのインスタンスを取得する方法がわかりません。プロパティ名には、プロパティの名前を文字列として返すようなラムダを使用できます。

要約すると、私は次のことを探しています。1)複雑な検証を可能にするある種の検証フレームワーク2)MVCのエラースタイリングが引き続き機能するようにModelState.AddModelErrorメソッドで使用するキーを識別する方法。

4

1 に答える 1

0

あなたは本当にFluentValidationを探しています

ただし、MVC2をサポートしているかどうかはわかりません。それは確かにMVC3とMVC4をサポートしています。

そのウェブサイトからのサンプルコード:

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Company).NotNull();
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}
于 2012-09-21T17:03:58.580 に答える