C# For循环中的MVC枚举模型绑定

C# For循环中的MVC枚举模型绑定,c#,asp.net-mvc,html-helper,C#,Asp.net Mvc,Html Helper,我有一个MVC5应用程序,我在其中使用for循环,这样我可以在传回控制器时绑定一个集合。这适用于我的所有属性,但基于DropDownFor类型的属性除外 问题是属性的名称未设置为product。[0]。TypeOfSubscription 我尝试了3种不同的方法:前2种方法的名称为[0]。TypeOfSubscription,第3种方法的名称为product[0]。TypeOfSubscription,但将其传递回控制器时没有绑定 我认为问题在于,第三个选项是绑定的,但由于它是隐藏的,所以无法获

我有一个MVC5应用程序,我在其中使用for循环,这样我可以在传回控制器时绑定一个集合。这适用于我的所有属性,但基于DropDownFor类型的属性除外

问题是属性的名称未设置为product。[0]。TypeOfSubscription

我尝试了3种不同的方法:前2种方法的名称为[0]。TypeOfSubscription,第3种方法的名称为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)
模型

用于循环视图

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

对于DropDownListFor,当数据发布回控制器时,所选值会丢失,因此我们需要有一个隐藏的文本框来保存所选值

尝试使用一个文本框并隐藏它来保存该值,或者使用另一个“数据-属性”

将枚举的定义移到VmStoreProducts类之外

for循环将命名选择项

[0].TypeOfSubscription
[1].TypeOfSubscription
....
假设您的操作方法是public ActionResult AddToCartIEnumerable 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" })

这也适用于其他属性

第一个是正确的用法,第二个没有意义,因为您无法覆盖name属性,第三个没有意义-它将只回发初始值。name属性将为[0].TypeOfSubscription,因为这是您要绑定到的属性的名称。请发布您的模型和for循环。我已经发布了for循环的模型和视图。我正在考虑使用Jquery编写一些内容,以便在枚举值更改时更新隐藏文本框的值。我确信这会起作用,但不知道是否确实可行st practice。这是我最初尝试的方法,我更改为当前方法,因为没有发生模型绑定。我已在上面添加了我的控制器方法,并且我显示的将绑定到控制器中的列表。请注意,名称属性必须为[0]。名称[0]。TypeOfSubscription[1]。名称[1]。TypeOfSubscription等不是产品[0].Name否则它不会绑定名称属性与我的模型完全相同,即名称、订阅类型等。如果我输入@Html.TextBoxproduct[++@i++]。名称,模型[i]。名称绑定,如果我输入@Html.HiddenForm=>m[i]。名称不适用于int i=0;im[i].Name}将呈现[0].Name、[1].Name等。正确,这正是它所做的,但它没有绑定。因此,我必须将字符串product放在[i].Name前面,以使其绑定,因此它现在呈现为产品[i].Name,并绑定到传递给action方法的变量product
@Html.HiddenFor(m => m[i].Name)
@Html.TextBoxFor(m => m[i].Name, new { @readonly = "readonly" })