2

フォームからバインドする複雑なオブジェクトがあります。モデル バインダーは次のようになります。

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    var form = new MyForm();

    var myObject = ...; //try to load up the object

    /* logic to populate values on myObject */
    form.MyObject = myObject;

    bindingContext.ModelState.SetModelValue(bindingContext.ModelName, new ValueProviderResult(form, "", CultureInfo.CurrentUICulture));
    return form;
}

そして、それは本来あるべきことをしています。そこから正しく入力MyFormされ、同じ MyForm インスタンスへの参照が ModelState に含まれています。DataAnnotationsただし、フォームはまたは my検証を使用して検証されませんCustomValidation。その検証を行うにTryValidateModel()は、コントローラーに呼び出しを追加する必要があります。

[HttpPost]
public ActionResult ProcessMyForm(MyForm form)
{
    //ModelState has the MyForm instance inside of it
    //TryValidateModel(ModelState); //this does not work
    TryValidateModel(form); //this works
    if (!ModelState.IsValid)
    {
        return View("Complete", form);
    }
    return RedirectToAction("Index");
}

カスタム検証を呼び出すだけでなく、ModelState.IsValid の値も更新します。

タイトルの質問に加えて、これによりいくつかの質問が発生します。

  1. 正しく検証されるフォームの同じインスタンスへの参照があるのにTryValidateModel(ModelState)、フォームを検証しないのはなぜですか?ModelStateTryValidateModel(form)

  2. TryValidateModel(form)の値ModelState.IsValidが更新されるのはなぜですか?

  3. 一般に、なぜバインダーが更新を担当するのModelStateですか?

4

1 に答える 1

1

ModelBinder の責任は、リクエストからの値を使用しているモデルにバインドすることです。

ModelState プロパティは、モデルの現在の状態を含む単なる辞書です。エラーリストのようにモデル状態を見てください。

カスタム ModelBinder がある場合は、リクエストの値を選択したクラスにマップします。これは、actionmethod へのパラメーターとして終了します。

ModelBinder は値をバインドするときに実行されるため、ModelBinder が ModelState の更新を担当することに同意しません。

後で TryValidateModel (または ValidateModel ) を実行すると、発生したエラーで ModelState プロパティが更新されます。検証メソッドにさまざまなタイプを使用することもできます (DataAnnotations、IValidatableObject...)

于 2011-03-10T19:39:33.837 に答える