3

私は次の ViewModels を持っています:

public class MyViewModel
{
  public BaseViewModel mySubViewModel;
}

public class ChildViewModel: BaseViewModel
{}

次に、ChildViewModel 型のプロパティを含む MyViewModel モデルを作成します。ビューでは、問題なく表示されます。

次に、保存ボタンを押してモデルに変更を送信し、次のコントローラーを呼び出します。

    [HttpPost]
    public ActionResult Edit(MyViewModel model)
    {
        return null;
    }

驚いたことに、プロパティ mySubViewModel は、 ChildViewModel ではなく BaseViewModel 型になりました! ここで何が起こっているのかわかりません。私は何を間違っていますか?

4

1 に答える 1

7

驚いたことに、プロパティmySubViewModelは、ChildViewModelではなくBaseViewModelタイプになりました。ここで何が起こっているのかわかりません。私は何を間違っているのですか?

驚かないでください。あなたは何も悪いことをしていません。これは仕様によるものです。デフォルトのモデルバインダー、コントローラーアクションがMyViewModel引数を取り、POSTリクエストの内容をそれにバインドしようとしていることを確認します。デフォルトのモデルバインダーには、派生クラス(たとえば、ChildViewModelあなたの場合)そしてあなたはそれらの派生クラスがここでインスタンス化されて使用されることを望みます。この具象ビューモデルインスタンスをGETアクションからビューに渡したという事実は、POSTアクションには影響しません。HTTPと、デフォルトのモデルバインダーが認識するものの観点から考えてください。たとえば、このPOSTアクションは、フォームの送信からではなく、まったく異なるクライアントから呼び出すことができると考えてください。たとえば、POSTアクションへのHTTPリクエストを実行するiPhoneアプリケーションである可能性があります。ほら、今では完全に理にかなっています。デフォルトのモデルバインダーは、POSTリクエストのペイロードとアクション引数として指定したタイプのみを確認できます。そしてそれが彼がしていることです=>それはこのタイプをインスタンス化し、POSTペイロードデータからそのプロパティをバインドします。

したがって、1つの可能性は、必要なビューモデルの具体的なインスタンスをインスタンス化するカスタムモデルバインダーを作成することです。私はそのようなカスタムモデルバインダーをで例示しましたthis post。この例では、インスタンス化するビューモデルの具体的なタイプを含む非表示フィールドをフォーム内に含め、カスタムモデルバインダーはこの情報を使用して実行時にこのタイプを作成します。

于 2013-02-02T22:39:40.763 に答える