簡體   English   中英

For循環中的MVC枚舉模型綁定

[英]MVC Enum Model Binding in For Loop

我有一個MVC 5應用程序,其中使用了for循環,因此當傳遞回控制器時可以綁定一個集合。 除了基於DropDownFor類型的屬性外,這對我的所有屬性均適用。

問題是該屬性的名稱未設置為“ product。[0] .TypeOfSubscription。

我嘗試了3種不同的方法:前兩種方法的名稱以[0] .TypeOfSubscription結尾,而第三個方法的名稱正確為product [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; }


    }

對於循環-視圖

@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 });
        }

將枚舉的定義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" })

這也適用於其他屬性

嘗試使用文本框並將其隱藏以保留該值或使用另一個'data-property

對於DropDownListFor,當數據回傳到控制器時,所選值會丟失,因此我們需要有一個隱藏的文本框來保留所選值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM