3

ASP.NET MVC3 アプリケーションで作業していますが、特定のエディター ビューでプロパティを操作する DropDownListFor を取得できません。

私のモデルは でPerson、人物には「人物タイプ」を指定するプロパティがあります。PersonType名前/説明と ID を含むクラスです。PersonTypeという静的/共有クラスを介して、アプリケーション内で使用可能な にアクセスできますApplicationSettings

私のテンプレートの編集ビューで、デバッグ用Personに作成しました:SelectList

@ModelType MyNamespace.Person
@Code
    Dim pTypesSelectList As New SelectList(MyNamespace.ApplicationSettings.PersonTypes, "ID", "Name", Model.PersonType.ID)
End Code

次に、これを my のプロパティにバインドされたSelectListへのパラメーターとして提供します。DropDownListForPersonTypePerson

また、デバッグ目的Selectedで各アイテムのプロパティを出力しています。SelectList

<div style="text-align: center; margin: 5px 0 0 0;">
    <div>
        @Html.LabelFor(Function(model) model.PersonType)
    </div>
    <div>
        @Html.DropDownListFor(Function(model) model.PersonType, pTypesSelectList)
        @Html.ValidationMessageFor(Function(model) model.PersonType)

        <br />
        <br />
        <!-- The following is debugging code that shows the actual value-->
        @Model.Type.Name
        <br />
        @Model.Type.ID
        <br />
        <br />

        <!--This section is to show that the select list has properly selected the value-->
        @For Each pitem In pTypesSelectList
            @<div>
                @pitem.Text selected: @pitem.Selected
            </div>
        Next
    </div>
</div>

Personビューは、PersonTypeプロパティが「Person Type # 2」である にバインドされており、これが選択されることを期待しています。ただし、このコードの HTML 出力は次のようになります。

<div style="text-align: center; margin: 5px 0 0 0;">
    <div>
    <label for="PersonType">PersonType</label>
    </div>
    <div>
        <select id="PersonType" name="PersonType">
            <option value="7e750688-7e00-eeee-0000-007e7506887e">Default Person Type</option>
            <option value="87e5f686-990e-5151-0151-65fa7506887e">Person Type # 1</option>
            <option value="a7b91cb6-2048-4b5b-8b60-a1456ba4134a">Person Type # 2</option>
            <option value="8a147405-8725-4b53-b4b8-3541c2391ca9">Person Type # 3</option>
        </select>
        <span class="field-validation-valid" data-valmsg-for="PersonType" data-valmsg-replace="true"></span>
        <br />
        <br />
        <!-- The following is debugging code that shows the actual value-->
        Person Type # 2
        <br />
        a7b91cb6-2048-4b5b-8b60-a1456ba4134a
        <br />
        <br />
        <!--This section is to show that the select list has properly selected the value-->
        <div>
            Default Person Type selected: False
        </div>
        <div>
            Person Type # 1 selected: False
        </div>
        <div>
            Person Type # 2 selected: True
        </div>
        <div>
            Person Type # 3 selected: False
        </div>
    </div>
</div>

ご覧のとおり、SelectList 内の項目の Selected プロパティが出力されており、3 番目の項目が「選択済み」であることを示しています。しかし、私を夢中にさせているのは、これに対応するオプションが選択されていないことです。

4

2 に答える 2

6

通常、SelectedプロパティはSelectList、他にオプションがない限り、HTML ヘルパーによって完全に無視されます。DropDownListFor他の方法で値を見つけることができる場合、その値を使用することを主張します。

この場合、model.PersonType( .ToString())の値を使用しますmodel.PersonType.IDが、SelectList.

詳細については、こちらの回答をご覧ください。

回避策

動作するはずの簡単な回避策の 1 つは、次のように設定することです。

ViewData["PersonType"] = model.PersonType.Id. 

ヘルパーは、ModelState が存在する場合、つまり POST で最初に ModelState を調べます。ModelState["PersonType"]投稿された実際の選択値が入力されるため、これはすでに機能しているはずです。

ModelState の後、最初に、そして次にのみ検索さViewDataViewData["PersonType"]ますViewData.Model.PersonType。つまり、モデルの値を に直接設定された値で「オーバーライド」できますViewData

より良い(IMO)ソリューション

それを解決するためのより一般的な「より良い方法」の方法 (これは、POST された ID を に戻すためにカスタム モデル バインダーを使用することも回避しますPersonType) は、ビューで完全なモデルを操作する代わりに、ViewModel を使用することです。

  • PersonTypeIDの代わりに - プロパティを持っていますPersonType
  • で入力しますPersonType.ID
  • あなたの見解でこれを使用してください
    • VB.NET: Html.DropDownListFor(Function(model) model.PersonTypeID)、または
    • C#:Html.DropDownListFor(model => model.PersonTypeID)
  • フォームが POST されたら、ViewModel ( PersonTypeID=>を含むPersonType) を POST アクションの実際のモデルに変換します。

これはより多くの作業のように思えるかもしれませんが、一般的にプロジェクトでは、インラインの Razor コードが多すぎるのを避けるために、データのビュー固有の表現が必要になることがよくあります。冗長で DRY にならないこともあり、多くの頭痛の種から解放される傾向があります。

于 2013-08-20T14:25:12.917 に答える
1

ビューをレンダリングする前の「PersonType」キーの ModelState が空であることは確かですか? JimmiTh がコメントしたように、最初に ModelState の値を検索します。それは私にも起こりました。試してみる @Html.DropDownList("PersonTypeFake", Function(model) model.PersonType, pTypesSelectList)と、正しいオプションが選択されるはずです。

于 2013-08-16T20:59:42.337 に答える