【问题标题】:How can you pass a list of objects in a model back to a controller? [duplicate]如何将模型中的对象列表传递回控制器? [复制]
【发布时间】:2014-02-01 00:40:22
【问题描述】:

更新:解决方案是使用 EditorTemplate。请参阅下面的解决方案:

我想向/从控制器传递模型,让我设置名称,并在未确定的角色上设置值(作为复选框)。当我检查回发时,我在模型中获得了 Name 的值,但 Roles 为空。如何判断哪些复选框被选中?

型号:

public class MyModel
{
    public string Name { get; set; }
    public IEnumerable<RoleItem> Roles { get; set; }
}

public class RoleItem
{
    public String Name { get; set; }
    public String Id { get; set; }
    public bool Selected { get; set; }
    public RoleItem(String id, String name, bool selected = false)
    {
        this.Name = name;
        this.Id = id;
        this.Selected = selected;
    }
}

剃须刀:

@model WebApplication1.Controllers.MyModel

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    @Html.TextBoxFor(m=>m.Name)

    foreach (var m in Model.Roles)
    {
        <div>
            @Html.Label(m.Id, m.Name)
            @Html.CheckBox(m.Id, m.Selected, new { id = @m.Id })
        </div>
    }
    <input type="submit"/>
}

【问题讨论】:

  • 你的 Controller->Model->Viewer 之间应该有一个消息服务

标签: asp.net-mvc razor


【解决方案1】:

目标:允许任何管理员将新用户添加到 Asp 身份表并为他们分配使用复选框在列表中定义的角色。

型号:

public class RegisterViewModel
{
    [Display(Name = "Name")]
    public string FullName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    public List<RoleItem> Roles { get; set; }

}

public class RoleItem
{
    public String Name { get; set; }
    public String Id { get; set; }
    public bool IsMember { get; set; }
}

控制器 (GET):读取数据库中的所有角色并将它们转换为 RoleItems 列表。这会将字符“r”添加到 id 字段中,因为某些浏览器会出现 id 以数字开头的问题。我们要确保默认选中“用户”组,因此我们在列表中找到该值并将 IsMember 属性设置为 true。我们检查请求以查看页面是否从成功的 POST 重定向到此处(见下文)

    // GET: /Account/AddUser
    [Authorize(Roles = "Administrators")]
    public ActionResult AddUser()
    {
        var rolesDb = new ApplicationDbContext();  //Users, Administrators, Developers, etc
        ViewBag.AddSuccess = Request["added"]=="1" ? true : false;

        var roleItems = rolesDb.Roles.Select(r => new RoleItem() { Id = "r" + r.Id, Name = r.Name, IsMember = false }).ToList(); //add an r to get around a browser bug
        var users = roleItems.FirstOrDefault(r => r.Name == "Users");  //Get the row that has the Users value and set IsMember=true
        if (users != null) 
            users.IsMember = true;
        var m = new RegisterViewModel() {Roles = roleItems};
        return View(m);
    }

视图:非常标准的东西。注意底部的@Html.EditorFor(x => x.Roles),它使用了一个编辑器模板(如下)

@model cherry.Models.RegisterViewModel
@{
    ViewBag.Title = "AddUser";
}

<h2>@ViewBag.Title.</h2>

@if (Convert.ToBoolean(ViewBag.AddSuccess))
{
    <text>User added!</text>
}

@using (Html.BeginForm("AddUser", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Create a new account.</h4>
    <hr />
    @Html.ValidationSummary()
    <div class="form-group">
        @Html.LabelFor(m => m.EmailAddress, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.EmailAddress, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.FullName, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.FullName, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.Password, new { value = Model.Password, @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ConfirmPassword, new {@class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.ConfirmPassword, new {value = Model.ConfirmPassword,  @class = "form-control" }) 
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Register" />
        </div>
    </div>

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

}

编辑器模板:

必须为模板指定与您为其创建模板的对象相同的名称。您还必须将此对象放在您正在为其设计的视图下方名为 EditorTemplates 的文件夹中,或者您可以将该文件夹放在共享文件夹中。

Views\Account\EditorTemplates\RoleItem.cshtml

@model cherry.Models.RoleItem
<div>
    @Html.CheckBoxFor(x => x.IsMember)
    @Html.LabelFor(x => x.IsMember, Model.Name)
    @Html.HiddenFor(x => x.Name)
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 2020-01-09
    相关资源
    最近更新 更多