C# MVC5 @Html.EnumDropDownListFor 在 "postback" 上失去选择
C# MVC5 @Html.EnumDropDownListFor loses selection on "postback"
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 中 - 当我创建一个产品以 return 到视图时,我为每种标题类型创建一个标题并将其添加到产品中。视图显示了我所期望的一切。
当我点击“创建”按钮时,产品和标题按预期 return 发送到控制器并且我验证了标题(不同的验证取决于类型)。我将任何错误添加到 ModelState,因此,ModelState.IsValid 是错误的。
我return回到视图return View(product);
调试此产品,所有标题都在产品中并且它们仍然具有正确的类型,但视图现在显示列表中的第一个枚举,用于所有标题而不是模型中实际存在的标题!
如果我将 EnumDropDown 更改为文本框,则会显示正确的类型,因此模型绝对正确:
我不确定为什么会这样,我希望有人可以提出修复建议?它是 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; }
}
处理集合中的下拉列表时,您需要自定义 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
属性 排除在绑定之外,并且在任何情况下您都应该使用视图模型来仅表示您想要 display/edit
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 中 - 当我创建一个产品以 return 到视图时,我为每种标题类型创建一个标题并将其添加到产品中。视图显示了我所期望的一切。
当我点击“创建”按钮时,产品和标题按预期 return 发送到控制器并且我验证了标题(不同的验证取决于类型)。我将任何错误添加到 ModelState,因此,ModelState.IsValid 是错误的。
我return回到视图return View(product);
调试此产品,所有标题都在产品中并且它们仍然具有正确的类型,但视图现在显示列表中的第一个枚举,用于所有标题而不是模型中实际存在的标题!
如果我将 EnumDropDown 更改为文本框,则会显示正确的类型,因此模型绝对正确:
我不确定为什么会这样,我希望有人可以提出修复建议?它是 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; }
}
处理集合中的下拉列表时,您需要自定义 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
属性 排除在绑定之外,并且在任何情况下您都应该使用视图模型来仅表示您想要 display/edit