C#MVC5 @ Html.EnumDropDownListFor失去对“回发”的选择

时间:2015-04-25 15:57:39

标签: c# asp.net view asp.net-mvc-5

MVC5 EF6

我有一个产品。产品可以有多个标题,标题的类型是枚举。

我正在开发产品的创建视图 - 模型是产品

查看:

            @for (int x = 0; x < Model.ProdTitles.Count; x++)
            {                    
                <tr>
                    <td>
                        @Html.TextBoxFor(model => model.ProdTitles.ToArray()[x].Title, new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.ProdTitles.ToArray()[x].Title, "", new { @class = "text-danger" })
                    </td>
                    <td>
                        @Html.EnumDropDownListFor(model => model.ProdTitles.ToArray()[x].TitleTypeID, new { @class = "form-control" })
                    </td>
                    <td>
                        @Html.EnumDropDownListFor(model => model.ProdTitles.ToArray()[x].CultureID, new { @class = "form-control" })
                    </td>
                </tr>
            }

在Controller中 - 当我创建产品以返回视图时,我为每种标题类型创建一个标题并将其添加到产品中。视图显示了我期望的一切。

Working as required

当我点击“创建”按钮时,产品和标题将按预期返回到控制器,并验证标题(根据类型进行不同的验证)。我将任何错误添加到ModelState,因此,ModelState.IsValid为false。

我返回查看return View(product); 调试此产品,所有标题都在产品中,并且它们仍然具有正确的类型,但View现在显示列表中的第一个枚举,对于所有标题而不是实际在模型中的标题!

Showing first enum for all titles

如果我将EnumDropDown更改为文本框,则会显示正确的类型,因此模型绝对正确:

proves model has the correct type

我不确定为什么会发生这种情况,我希望有人能提出修正建议吗?它是EnumDropDownFor中的错误吗?或者我做错了什么?

控制器代码:

    public ActionResult Create()
    {
        Product product = new Product();

        foreach (var enm in Utils.Enums.EnumHelper.GetValues<Utils.Enums.TitleType>())
        {
            product.ProdTitles.Add(new ProdTitle()
            {
                CultureID = Utils.Enums.CultureID.English_United_Kingdom,                    
                DateCreated = DateTime.Now,
                Title = "",
                TitleTypeID = enm
            });
        }

        return View(product);
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "ProdID,DateCreated")] Product product, ICollection<ProdTitle> prodTitles)
    {
        //ensure titles are all valid before saving
        for (int x = 0; x < prodTitles.Count; x++)
        {
            ProdTitle title = prodTitles.ToArray()[x];
            if (!title.IsValid)
            {
                ModelState.AddModelError(string.Empty, title.TitleTypeID + " title is invalid.");
            }
            product.ProdTitles.Add(title);
        }


        if (ModelState.IsValid)
        {
            db.Products.Add(product);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(product);
    }

ProdTitle模型

public partial class ProdTitle
{
    public long TitleID { get; set; }
    public long ProdID { get; set; }
    public Utils.Enums.TitleType TitleTypeID { get; set; }
    public string Title { get; set; }
    public Utils.Enums.CultureID CultureID { get; set; }
    public System.DateTime DateCreated { get; set; }

    public virtual Product Product { get; set; }
    public virtual DataSource DataSource { get; set; }
}

1 个答案:

答案 0 :(得分:2)

在处理集合中的下拉列表时,您需要自定义EditorTemplate

/Views/Shared/EditorTemplates/ProdTitle.cshtml

@model yourAssembly.ProdTitle

<tr>
  <td>
    @Html.TextBoxFor(m => m.Title, new { @class = "form-control" })
    @Html.ValidationMessageFor(m => m.Title, new { @class = "text-danger" })
  </td>
  <td>
    @Html.EnumDropDownListFor(m => m.TitleTypeID, new { @class = "form-control" })
  </td>
  <td>
    @Html.EnumDropDownListFor(m => m.CultureID, new { @class = "form-control" })
  </td>
</tr>

然后在主视图中

@model yourAssembly.Product
@using(Html.BeginForm())
{
  .... // other controls for properties of Product
  @Html.EditorFor(m => m.ProdTitles) // not in a loop!
}

然后将控制器修改为

public ActionResult Create(Product product)

注意:您当前的[Bind]属性会将ProdTitle属性从绑定中排除,并且无论如何您应该使用视图模型来仅表示您要显示/编辑的内容