asp.net MVC模型如何生成输入名称?

时间:2011-07-19 14:50:53

标签: asp.net-mvc-3 razor

在带有Razor标记的MVC的EditorFor视图中,如果你这样做:

@Html.TextBox("")

HTML提供了模型的正确输入名称,如下所示:

<input id="usr_Roles" name="usr.Roles" type="text" value="">

“usr.Roles”名称来自此EditorFor行:

@Html.EditorFor(modelItem => usr.Roles, "RoleList") 

不幸的是,我正在尝试生成一组名为“usr.Roles”的复选框。由于MVC呈现复选框的方式,我不能使用Html.Checkbox。我可以像这样手动生成它们:

@foreach (string roleName in Roles.GetAllRoles())
{
    string checkboxId = "checkbox_" + roleName;
    <input type="checkbox" name="usr.Roles" id="@checkboxId" value="@roleName" @Html.Raw(Model.Contains(roleName) ? "checked" : "") />
    <label for="@checkboxId">@roleName</label>
} 

上述方法有效,但仅限于我手动指定“usr.Roles”作为复选框名称。

我的问题是:在对象和属性的迷宫中,@Html.TextBox对象在哪里找到“usr.Roles”“usr-Roles”字符串?我可以自己找到并在复选框中使用它吗?

3 个答案:

答案 0 :(得分:7)

我不知道为什么你会想要手动生成复选框的ID和名称而不是简单地使用Html.CheckBoxFor帮助器为你完成所有这些,但是如果你有一些原因,这是如何:

@{
    var name = ViewData.TemplateInfo.GetFullHtmlFieldName("");
}

@foreach (string roleName in Roles.GetAllRoles())
{
    string checkboxId = "checkbox_" + roleName;
    <input type="checkbox" name="@name" id="@checkboxId" value="@roleName" @Html.Raw(Model.Contains(roleName) ? "checked" : "") />
    <label for="@checkboxId">@roleName</label>
} 

显然,这里显示纯粹出于某些教育目的。我真的会避免这种怪异,只需使用Html助手和编辑器模板。在您看来,令我震惊的另一件事是以下代码行:Roles.GetAllRoles()。就像您的视图正在查询数据一样。这是视图应该做的最后一件事。控制器负责查询数据,填充视图模型并将此视图模型传递给视图,以便它只显示数据。

让我们试着详细说明你的例子。根据我的理解,您试图显示每个角色的复选框列表,以便用户可以选择它们。

与往常一样,您可以从表达视图要求的视图模型开始:

public class MyViewModel
{
    public IEnumerable<RoleViewModel> Roles { get; set; }
}

public class RoleViewModel
{
    public string RoleName { get; set; }
    public bool Selected { get; set; }
}

然后你编写一个控制器动作来查询你的数据并填充视图模型:

public ActionResult Index()
{
    var roles = Roles.GetAllRoles();
    var model = new MyViewModel
    {
        Roles = roles.Select(role => new RoleViewModel
        {
            RoleName = role,
            Selected = ??????
        })
    };
    return View(model);
}

然后您将看到Index.cshtml视图:

@model MyViewModel
@Html.EditorFor(x => x.Roles)

以及将为Roles集合(~/View/Shared/EditorTemplates/RoleViewModel.cshtml)的每个元素呈现的相应编辑器模板:

@model RoleViewModel
@Html.CheckBoxFor(x => x.Selected)
@Html.LabelFor(x => x.Selected, Model.RoleName)

视图中不再有foreach个循环,不再有名称和ID的丑陋黑客,不再从视图中提取数据。

答案 1 :(得分:1)

据我所知,您想从模型中生成属性名称, 我建议你使用这个方法:

ExpressionHelper.GetExpressionText

来自System.Web.Mvc程序集

答案 2 :(得分:-1)

使用NameExtensions.NameFor HTML帮助器,这非常简单。

您可以像这样使用它:

@Html.NameFor(modelItem => usr.Roles)