3

我正在研究ASP.NET MVC3應用程序,我無法使用DropDownListFor在特定編輯器視圖中使用我的屬性。DropDownListFor未選擇SelectList中的選定項目

我的模型是Person,並且一個人有一個屬性指定它是「Person Type」。 PersonType是一個包含名稱/描述和ID的類。我可以通過名爲ApplicationSettings的靜態/共享類訪問應用程序中的可用PersonType

在爲編輯模板視圖我Person我已經創建了一個調試用SelectList

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

我再提供這個SelectList作爲參數綁定到我的PersonPersonType財產DropDownListFor

我還打印出每一個項目在SelectListSelected性能調試目的:

<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> 

視圖綁定到PersonPersonType屬性是「人員類型#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> 

正如你可以看到在選擇列表的項目打印所選屬性顯示,第三項是「選擇」。但是讓我瘋狂的是與此相對應的選項是未選中。

+0

你可以在你的ApplicationSettings類中發佈PersonTypes的代碼嗎? – ataravati

+0

可能看到例如這個:http://stackoverflow.com/questions/17691742/ - 通常,'SelectList'中的'Selected'屬性將被HTML助手完全忽略,除非沒有其他選項。如果'DropDownListFor'可以通過其他方式找到值,它會堅持這個值。在這種情況下,它將使用'model.PersonType'('.ToString()')的值 - 但這並不是你想要的,通過將'model.PersonType.ID'傳遞給'SelectList'來判斷。 – JimmiTh

+0

PersonType類的ToString方法返回它的名稱:將其與ID(Guid)進行比較永遠不會匹配。我如何繞過這個? – Frinavale

回答

6

通常,SelectList中的Selected屬性將被HTML助手完全忽略,除非沒有其他選項。如果DropDownListFor可以通過其他方式找到該值,那麼堅持要求使用該值。

在這種情況下,它會使用的model.PersonType.ToString())的價值 - 但是這不是你想要的,你所傳遞給SelectListmodel.PersonType.ID判斷。

更多的信息在the answer here

解決方法

一個簡單的解決辦法,應該工作是設置:

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

助手看起來的ModelState第一,如果它存在 - 即在POST。這應該已經工作,因爲ModelState["PersonType"]將填充所發佈的實際選定值。

ModelState中後,它會看在ViewData - 與ViewData["PersonType"]第一,然後纔是ViewData.Model.PersonType。換句話說,您可以直接在ViewData上設置值來「覆蓋」模型上的值。

更好(IMO)的解決方案

更普遍的,「更好的做法」,辦法解決呢(這也避免了爲了將POST'ed ID轉換回PersonType具有自定義模型粘合劑)是用的,而不是在你看來全款工作一個ViewModel:

  • 有一個PersonTypeID性能 - 而不是PersonType
  • PersonType.ID
  • 使用填充它這個在你看來
    • VB.NET:Html.DropDownListFor(Function(model) model.PersonTypeID),或
    • C#:Html.DropDownListFor(model => model.PersonTypeID)
  • 當形式是POST'ed,翻譯視圖模型(包括PersonTypeID =>PersonType)回到POST Action的實際模型中。

這似乎是更多的工作,但一般也往往是多次在一個項目中,您需要更多的數據視圖特定表示,以避免過多的直列剃刀代碼 - 從業務對象,以便翻譯成查看模型,雖然它可能看起來多餘,有時反DRY,但往往會讓你頭痛不已。

+0

在ViewBag中設置值的解決方法是爲我修復的。難以置信的是,在2015年這仍然是一個問題。感謝細節。 – agarcian

+0

這完全破碎了。除非模型屬性是「string」類型,否則我無法選擇它。對於多選下拉菜單沒用,因爲它將所有內容組合成逗號分隔的列表,這只是令人討厭的,如果您的值包含逗號,則不起作用。 2016年破產。 – Triynko

1

你確定你的ModelState for「PersonType」鍵在渲染視圖之前是空的嗎?正如JimmiTh所評論的那樣,首先要在ModelState中搜索值。它也發生在我身上,你可以嘗試 @Html.DropDownList("PersonTypeFake", Function(model) model.PersonType, pTypesSelectList)它應該選擇正確的選項。

+0

我剛剛檢查過,是的,ModelState [「PersonType」]是空的(null);然而,直到我設置ViewData它才工作。 – Frinavale