3

関連する質問がいくつかありますが、うまくいく答えが見つかりません。

次のモデルがあると仮定します。

public class EditorViewModel
{
  public Account Account {get;set;}
  public string SomeSimpleStuff {get;set;}
}

public class Account
{
  public string AccountName {get;set;}
  public int MorePrimitivesFollow {get;set;}
}

そして、次のことを行う拡張ビューViewPage<EditorViewModel>:

<%= Html.TextBoxFor(model => model.Account.AccountName)%>
<%= Html.ValidationMessageFor(model => model.Account.AccountName)%>
<%= Html.TextBoxFor(model => model.SomeSimpleStuff )%>
<%= Html.ValidationMessageFor(model => model.SomeSimpleStuff )%>

そして私のコントローラーは次のようになります:

[HttpPost]
public virtual ActionResult Edit(EditorViewModel account)
{ /*...*/ }

DefaultModelBinder を取得して EditorViewModel を適切にバインドするにはどうすればよいですか? 特別なことを何もせずに、すべてが null またはデフォルトの EditorViewModel の空のインスタンスを取得します。

私が最も近いのは、UpdateModel手動で呼び出すことです:

[HttpPost]
public virtual ActionResult Edit(EditorViewModel account)
{
    account.Account = new Account();
    UpdateModel(account.Account, "Account");
    // this kills me:
    UpdateModel(account);

これにより Account プロパティ モデルが正常に更新されますが、account(EditorViewModel の残りのパブリック プロパティを取得するために) UpdateModel を呼び出すと、まったく役に立たない「タイプのモデル ... を更新できませんでした」というメッセージが表示されます。内部例外がないため、何が問題なのかわかりません。

これをどうすればいいですか?

4

1 に答える 1

4

アクション メソッドへのパラメーターがaccountという名前であることがわかり、 account.accountnameという名前の受信フォーム フィールドが表示されるため、バインダーは混乱しています。そのため、EditorViewModel で AccountName プロパティを探しています。

パラメータの名前を受信フォーム フィールドと競合しない名前に変更するか、パラメータに [Bind(Prefix = "")] 属性を追加することで、これを修正できます。この属性は、「パラメーターの名前がaccountであるという事実を無視し、代わりに空の文字列名を付けたふりをする」ことを示しています。次に、バインダーはaccount.account.accountnameの代わりにaccount.accountnameを探します。

編集 - 詳細情報:

バインダーは、fooという名前の複雑なパラメーターを検出すると、現在の要求で *foo.** という名前のものを調べます。したがって、たとえば、パラメーターの名前がfooで、その型にFirstNameという名前のプロパティがある場合、受信値はfoo.FirstName=Johnであると予想されます。

ただし、バインダーが要求の一部として *foo.** を認識しない場合は、* を直接 ( fooプレフィックスなしで) 検索します。そのため、要求に *foo.** が存在しない限り、FirstName=Johnを送信でき、バインダーはこれを正しく理解します。ただし、要求の一部として *foo.** がある場合、FirstName=Johnの値は FirstName プロパティと一致しません。

これで、アクション メソッドのパラメーターにそのプロパティの 1 つと同じ名前を付けると、このロジックがどのように破棄されるかがわかります。

于 2010-04-01T23:16:43.690 に答える