2014-09-25 22 views
0

我有一個MVC 5應用程序,我使用的for循環,所以我可以綁定一個集合時傳回控制器。這適用於我所有的屬性,除了基於DropDownFor類型的屬性。MVC枚舉模型綁定在For循環

的問題是該屬性的名稱沒有設置成「產品[0] .TypeOfSubscription

我試圖3種不同的方式:該第一2方法最終獲得的名稱[0] .TypeOfSubscription和第三個具有正確名稱的產品[0] .TypeOfSubscription,但沒有綁定發生時,我將它傳回控制器。

我認爲問題是第三個選項是綁定,但因爲它隱藏它沒有得到分配的選定值。

@Html.EnumDropDownListFor(modelItem => Model[i].TypeOfSubscription) 

@Html.EnumDropDownListFor(modelItem => Model[i].TypeOfSubscription, 
              new { name = "product[" + @i + "].TypeOfSubscription"}) 

@Html.Hidden("product[" + @i + "].TypeOfSubscription", 
              Model[i].TypeOfSubscription) 

型號

public class VmStoreProducts 
    { 
     public VmStoreProducts() 
     { 
      NoOfUsers = 1; 
     } 

     public enum SubscriptionType 
     { 
      Monthly, 
      Annual 

     } 
     public int MojitoProductId { get; set; } 
     [Display(Name = "Category")] 
     public string ProductCategory { get; set; } 
     public virtual string Name { get; set; } 
     public string Description { get; set; } 
     [Display(Name = "Image")] 
     public byte[] ImageData { get; set; } 
     [Display(Name = "Type of Subscription")] 
     public SubscriptionType TypeOfSubscription { get; set; } 
     public decimal Price { get; set; } 
     [Display(Name = "No. of Users")] 
     public int NoOfUsers { get; set; } 

     [Display(Name = "Total Price")] 
     [DisplayFormat(DataFormatString = "{0:C}")] 
     public decimal TotalPrice { get; set; } 


    } 

For循環 - 查看

@model PagedList.IPagedList<VmStoreProducts> 
@using Mojito.Domain 
@using PagedList.Mvc; 
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" /> 
@{ 
    ViewBag.Title = "Index"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<h2>Mojito Products</h2> 
<div class="col-md-9"></div> 
<div class="col-md-3"> 
    @using (Html.BeginForm("Index", "MojitoProducts", FormMethod.Get)) 
    { 
     <p> 
      @Html.TextBox("SearchString", ViewBag.CurrentFilter as string) 
      <input type="submit" value="Search" /> 
     </p> 
    } 
</div> 
@using (Html.BeginForm("AddToCart", "ShoppingCart", FormMethod.Post)) 
{ 
    <table class="table"> 
     <tr> 
      <th> 
       @Html.DisplayNameFor(model => model.FirstOrDefault().ImageData) 
      </th> 
      <th> 
       @Html.ActionLink("Category", "Index", new { sortOrder = ViewBag.SortByCategory, currentFilter = ViewBag.CurrentFilter }) 
      </th> 
      <th> 
       @Html.ActionLink("Product", "Index", new { sortOrder = ViewBag.SortByProduct, currentFilter = ViewBag.CurrentFilter }) 
      </th> 
      <th> 
       @Html.DisplayNameFor(model => model.FirstOrDefault().Description) 
      </th> 
      <th> 
       @Html.DisplayNameFor(model => model.FirstOrDefault().TypeOfSubscription) 
      </th> 
      <th> 
       @Html.ActionLink("Price", "Index", new { sortOrder = ViewBag.SortByPrice, currentFilter = ViewBag.CurrentFilter }) 
      </th> 
      <th> 
       @Html.DisplayNameFor(model => model.FirstOrDefault().NoOfUsers) 
      </th> 
      <th> 
       @Html.DisplayNameFor(model => model.FirstOrDefault().TotalPrice) 
      </th> 

      <th></th> 
     </tr> 

     @for (int i = 0; i < Model.Count; i++) 
     { 

      <tr> 
       <td> 
        @if (Model[i].ImageData != null) 
        { 
         <div class="pull-left" style="margin-right: 10px"> 
          <img class="img-thumbnail" width="75" height="75" 
           src="@Url.Action("GetImage", "MojitoProducts", 
              new { Model[i].MojitoProductId })" /> 
         </div> 
        } 
       </td> 
       <td> 
        @Html.DisplayFor(modelItem => Model[i].ProductCategory) 
       </td> 
       <td> 
        @Html.TextBox("product[" + @i + "].Name", 
           Model[i].Name, new { @readonly = "readonly" }) 
       </td> 
       <td> 
        @Html.DisplayFor(modelItem => Model[i].Description) 
       </td> 
       <td> 
        @Html.EnumDropDownListFor(modelItem => Model[i].TypeOfSubscription) 

        @Html.EnumDropDownListFor(modelItem => Model[i].TypeOfSubscription, 
              new { name = "product[" + @i + "].TypeOfSubscription"}) 

        @Html.TextBox("product[" + @i + "].TypeOfSubscription", 
             Model[i].TypeOfSubscription, new { hidden=true }) 
       </td> 
       <td> 
        @Html.TextBox("product[" + @i + "].Price", 
         Model[i].Price, new { @readonly = "readonly", style = "width:50px" }) 
       </td> 
       <td> 
        @Html.TextBox("product[" + @i + "].NoOfUsers", 
         Model[i].NoOfUsers, new { type = "number", min = "0", style = "width:50px" }) 
       </td> 
       <td> 
        @Html.TextBox("product[" + @i + "].TotalPrice", 
         Model[i].TotalPrice, new { style = "width:50px" }) 
       </td> 
       <td> 
        <div class="pull-right"> 
         @if (Request.Url != null) 
         { 
          @Html.Hidden("product[" + @i + "].MojitoProductId", 
             Model[i].MojitoProductId) 
          @Html.Hidden("returnUrl", Request.Url.PathAndQuery) 
         } 

        </div> 

       </td> 
      </tr> 
     } 
     <tr> 
      <td colspan="6"> 
       <div class="pull-right"> 
        <input type="submit" class="btn btn-success" value="Add to cart" /> 
       </div> 
      </td> 
     </tr> 



    </table> 

} 

控制器方法

public ActionResult AddToCart(List<VmStoreProducts> product, string returnUrl) 
     { 
      ShoppingCart cartObjects = (Session["CartObjects"] as ShoppingCart) ?? new ShoppingCart(); 
      Session["CartObjects"] = cartObjects; 

      foreach (var item in product) 
      { 
       if (item.NoOfUsers > 0) 
       { 
        cartObjects.AddItem(item); 
       } 

      } 

      return RedirectToAction("Index", new { returnUrl }); 
     } 
+0

第一個是正確的用法(第二個是毫無意義的你不能重寫'name'屬性,第三個沒有任何意義 - 它只會回傳初始值)。 name屬性將是'[0] .TypeOfSubscription',因爲那是你綁定的屬性的名稱。請張貼您的模型和'for'循環 – 2014-09-25 07:23:22

+0

我已經發布了模型和視圖for for循環。我正在考慮用Jquery編寫一些東西,以便在枚舉值更改時更新隱藏文本框的值。我相信這會起作用,但不知道這是否是最佳做法。 – ccocker 2014-09-25 08:00:25

回答

1

移動枚舉的定義VmStoreProducts

public enum SubscriptionType 
{ 
    Monthly, 
    Annual 
} 

public class VmStoreProducts 
{ 
    public VmStoreProducts() 
    { 
    NoOfUsers = 1; 
    } 
    public int MojitoProductId { get; set; } 
    .... 
} 

for循環將命名選擇外

[0].TypeOfSubscription 
[1].TypeOfSubscription 
.... 

它將在回發上正確綁定(假設您的操作方法是public ActionResult AddToCart(IEnumerable<VmStoreProducts> products) {...

另外,請勿使用

@Html.TextBox("product[" + @i + "].Name", Model[i].Name, new { @readonly = "readonly" }) 

既然你已經使用了隱藏的輸入似乎更適合在同一物業的DisplayFor,所以

@Html.HiddenFor(m => m[i].Name) 

,或者如果你想顯示兩次

@Html.TextBoxFor(m => m[i].Name, new { @readonly = "readonly" }) 

這適用於其他屬性以及

+0

這就是我最初嘗試過的,我改變了我當前的方法,因爲沒有發生模型綁定。我還添加了我的控制器方法以及 – ccocker 2014-09-25 12:13:28

+0

我已經顯示的將綁定到控制器中的List 。注意'name'屬性必須是'[0] .Name','[0] .TypeOfSubscription','[1] .Name','[1] .TypeOfSubscription'等等(不是'product [0] .Name' )否則它不會綁定 – 2014-09-25 12:25:54

+0

名稱屬性與我的模型完全相同,即名稱,TypeOfSubscription等。如果我把@ Html.TextBox(「product [」+ @i +「] .Name」, Model [i] .Name)它綁定,如果我把@ Html.HiddenFor(m => m [i] .Name)它不 – ccocker 2014-09-25 12:27:12

-1

在DropDownListFor的情況下,當數據被調回控制器,選擇的值丟失,所以我們需要有一個隱藏的文本框來保持選定的值

0

試試你唱一個文本框和隱藏它堅持的價值或使用他人的財產數據 -