我正在使用MVC创建一个表单并使用[ControlType]For([expression])
辅助方法(EG Html.TextBoxFor(...)
)
要将数据绑定到控件,我使用以下ViewModel:
public class UserViewModel
{
//The Model that will be used to bind data to the elements
public UserModel User { get; set; }
//Used to bind selectable options to DropDownLists
public SelectList DescentTypes { get; set; }
public SelectList GenderTypes { get; set; }
}
使用时,控件的名称设置为name="Property.SubProperty"
(EG name="User.Id"
),但我希望它在我的html表单上显示为name="Id"
。
是否可以在不必编写大量自定义代码的情况下执行此操作,以便框架可以将其转换回ViewModel(UserViewModel)或仅转换为Model(用户)本身?
答案 0 :(得分:1)
我建议保留默认命名,除非你有充分的理由改变它。 ID(您的问题似乎倾向于)更灵活。
ID不会随表单一起提交,因此您可以根据需要设置它们,而不会破坏模型绑定。默认情况下,它们是分层的,但您可以内联覆盖它们:
@Html.TextBoxFor( o => o.UserName, new { id = "foo" } )
当然,这是手工作业。
如果最关心的是外部JS / CSS,我建议在你的(CSS / jQuery /无论)选择器而不是ID中使用类名和data-*
属性。
@Html.TextBoxFor( o => o.User.UserName, new { data_role="grand-total" } )
它仍然是手动的,但它具有描述性且独立于ID。
有时我在视图中使用一段脚本来初始化一个更大的JS类,其中的数据最容易直接在视图中使用。这使得大部分脚本驻留在外部文件中,同时允许使用动态值对其进行初始化。这不仅仅是ID。
供参考,假设您想要更改ID 和名称。
HtmlHelper
扩展方法以创建所需的标记。您可以包装不接受表达式的现有方法,并将显式值传递给它们以指示您想要的名称。ModelBinder
以映射原始表单集合。可以通过装饰属性来解决项目#3,以指示应如何执行命名以及模型绑定应如何映射。这很快就会变得复杂。
public class UserViewModel
{
// use this metadata to determine how to handle properties on this member
[Flatten]
public UserModel User { get; set; }
public SelectList DescentTypes { get; set; }
public SelectList GenderTypes { get; set; }
}
通过直接向其添加User
的属性来展平视图模型。看起来您正在从域模型中构建视图模型。这通常不是一个好主意。我建议reading the pros/cons of binding directly to domain models。
单独留下命名。它真的没有伤害任何东西,它让生活变得轻松。您可以使用帮助程序方法避免在客户端代码中直接使用名称/ ID。
例如:
// JavaScript + Razor
var name = "@Html.NameFor( o => o.User.Id )";
alert(name);