3

ASP.Net MVC 2 を使用していますが、DropDownList を適切にバインドするのに問題があります。

厳密に型指定された ViewModel と HTML.DropDownListFor ステートメントを使用して、View にドロップダウンを作成しています。このステートメントは、DropDown を ViewModel の単純なフィールドにバインドするだけの「通常の」シナリオでは正常に機能します。ViewModel に複数のオブジェクトのリスト (配列) が含まれており、これらの各オブジェクトのフィールドを (個別の) ドロップダウンにバインドする必要がある場合、このシナリオの使用に問題があります。その場合、ドロップダウンは正しい初期値を取得しません。

たとえば、複数のアドレスを持つことができる人がいる場合です。各住所は、Street、City、および State で構成されます。状態をドロップダウンとして表示したい。私のモデルは次のとおりです。

public class PersonModel : CommonViewModel
{
    public IList<SelectListItem> AvailableStates { get; set; }

    public string Name { get; set; }

    public IList<AddressModel> Addresses { get; set; }

    public PersonModel()
    {
        AvailableStates = GenerateStates();
    }

    private IList<SelectListItem> GenerateStates()
    {
        List<SelectListItem> items = new List<SelectListItem>();
        items.Add(new SelectListItem() { Text = "WA", Value = "WA" });
        items.Add(new SelectListItem() { Text = "NY", Value = "NY" });
        items.Add(new SelectListItem() { Text = "IH", Value = "IH" });
        items.Add(new SelectListItem() { Text = "FL", Value = "FL" });
        items.Add(new SelectListItem() { Text = "CA", Value = "CA" });

        return items;
    }
}

public class AddressModel
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}

今私のビューでは、次のようなものを使用したいと思います:

<% using (Html.BeginForm("SubmitPersonDetails", "Home", new { actionMode = "Person"}, FormMethod.Post, new { id = "SubmitPersonForm" }))
   {%>
    <div class="formrow longinput">
    <%= Html.LabelFor(person => person.Name)%>
    <%= Html.TextBoxFor(person => person.Name)%>
</div>
<h4>Addresses</h4>
<% for (int i = 0; i < Model.Addresses.Count; i++) { %>
<div class="formrow">
<%= Html.TextBoxFor(person => person.Addresses[i].Street)%>
<%= Html.TextBoxFor(person => person.Addresses[i].City)%>
<%--<%= Html.TextBoxFor(person => person.Addresses[i].State)%>--%>
<%= Html.DropDownListFor(person => person.Addresses[i].State, Model.AvailableStates) %>
</div>
<% } %>
 <input class="button primary" type="submit" value="Submit" name="Submit" />
<% } %>

テキストボックスの場合、これは正常に機能します (状態にテキストボックスを使用する場合も、コメントアウトされたビットを参照してください)。ドロップダウンは正しく生成されますが、正しい値に設定されていません。ドロップダウンで値を選択してフォームを送信すると、正しい値がモデルに戻されます。

また、Address 部分を UserControl に配置しようとしましたが、これは何度かレンダリングされます。Html.RenderPartial を使用して UserControl をレンダリングすると、正しい値が DropDOwn に設定されますが、Postback ではモデルが正しく設定されません。EditorFor を使用して UserControl をレンダリングすると、上記のコードと同じ問題が発生します。ドロップダウンは正しい初期値を取得しませんが、ポストバックではモデルで設定された選択値を取得します。

私が試したもう1つのことは、アドレスをリストではなく、代わりにビューモデル(プロパティ:Address1、Address2、Address3)でいくつかのアドレスをハードコーディングしてから、次を使用することです: <%= Html.DropDownListFor(person => person.Address1.State, Model .AvailableStates) %> この場合、DropDown は正しい値を取得します。明らかに、柔軟性がないためにこの回避策を使用したくありません。

私は何を間違っていますか?私はMVCが初めてなので、私のアプローチ全体が間違っているのでしょうか?

4

1 に答える 1

9

DropDownListForこれは、使用しているような複雑なラムダ式 (配列インデックス アクセスを含むラムダ式) から値を抽出できないヘルパーの制限です。考えられる回避策の 1 つは、次のとおりです。

<%= Html.DropDownListFor(
    person => person.Addresses[i].State, 
    new SelectList(
        Model.AvailableStates, 
        "Text", 
        "Value", 
        Model.Addresses[i].State
    )
) %>

SelectList コンストラクターで同じ値を渡すようになったので少し見苦しくなりますが、今度は DropDownListFor ヘルパーが対応するオプションを適切に設定できるようになります。

于 2012-05-08T21:41:24.160 に答える