我有一个.net MVC页面,其中有一个用于从数据库编辑实体的表单。表单中有一些动态选择列表字段,需要从数据库中填充。
我传递一个包含实体数据的PageView模型,以及填充选择列表的实体列表,如下所示:
public class EditPortalPage
{
public PortalViewModel Data { get; set; }
public IEnumerable<SelectListItem> Cultures { get; set; }
}
在我的视图中我有
@model Website.Models.Portals.EditPortalPage
位于页面顶部
我可以轻松填充表单:
@Html.EditorFor(model => model.Data.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.LabelFor(model => model.Data.Name)
@Html.ValidationMessageFor(model => model.Data.Name, "", new { @class = "text-danger" })
@Html.DropDownListFor(model => model.Data.DefaultCultureId, new SelectList(Model.Cultures, "Value", "Text"), new { @class = "mdb-select colorful-select dropdown-info" })
@Html.LabelFor(model => model.Data.DefaultCultureId)
@Html.ValidationMessageFor(model => model.Data.DefaultCultureId, "", new { @class = "text-danger" })
问题是这会为我的表单字段产生混乱的Id和Name属性。在上面的例子中,它产生:
Name Field ID: Data_Name
Name Field Name: Data.Name
设置它的正确方法是什么,所以名称和ID不包含'数据'前缀
我可以直接将数据模型传递给表格吗?
答案 0 :(得分:1)
HtmlHelper
方法根据属性的名称生成name
和id
属性。在您的情况下,它是一个嵌套属性,因此它为Data.
属性生成name
前缀,在id
属性的情况下,它替换.
(点)使用_
(下划线),以便可以在jquery选择器中使用id
(否则点和后面的文本将被解释为类选择器。
基于属性名称的id
属性可以确保一个唯一的id
(因此有效的html),我不确定为什么你认为它'混乱',但你总是可以覆盖使用
@Html.EditorFor(m => m.Data.Name, new { htmlAttributes = new { id = "xxx", @class = "form-control" } })
如果要在css或javascript / jquery选择器中使用<input id="xxx" .... />
(这是xxx
属性的唯一目的),将呈现id
然而,name
属性肯定不会“搞砸”,如果它被更改,则在提交时它不会绑定到您的模型。在任何情况下,您都不应该在使用name
方法时尝试更改HtmlHelper
属性。
我猜你(错误地)将你的数据模型用作POST方法中的参数,在这种情况下你可以使用Prefix
属性的[Bind]
属性(尽管是{{ 1}}属性永远不应该与视图模型一起使用)
[Bind]
删除public ActionResult Edit([Bind(Prefix = "Data")]PortalViewModel model)
前缀并绑定到"Data."
。
然而,这里真正的问题是你错误地使用了视图模型。查看模型(尤其是在编辑数据时)不应包含数据模型。它们仅包含视图中所需的数据模型的属性。视图模型的一些优点包括分离关注,防止不足和过度发布攻击,添加不适用于数据模型的显示属性的功能,以及添加其他视图特定属性的功能。在你的情况下,你已经否定了除了最后一点之外的所有事情。您应该查看模型
PortalViewModel
并在POST方法中,将视图模型映射到数据模型并保存数据模型。另请参阅What is ViewModel in MVC?。
作为旁注,在public class EditPortalPage
{
public string Name { get; set; }
[Display(Name = "Culture")]
[Required(ErrorMessage = "Please select a culture")]
public int? SelectedCulture { get; set; } //nullable and Required to protect against under-posting attacks
... // other properties of PortalViewModel that you need in the view
public IEnumerable<SelectListItem> Cultures { get; set; }
}
方法中使用new SelctList(..)
是无意义的额外开销 - 它只是从第一个创建另一个相同的DropDownList()
,而您的代码应该只是
IEnumerable<SelectListItem>
答案 1 :(得分:0)
如果我正确理解了Q,您可以使用部分"_data.cshtml"
:
@model PortalViewModel
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
将数据传递给视图中的部分:
@Html.Partial("_data",model.Data)