C# @Html.CheckboxFor nor<;输入>;将复选框值传递回控制器(绑定问题)

C# @Html.CheckboxFor nor<;输入>;将复选框值传递回控制器(绑定问题),c#,html,asp.net-mvc,razor,C#,Html,Asp.net Mvc,Razor,所以现在我正在尝试创建一个用户管理页面。页面的主模型实际上是一个IdentityUser,但我试图从视图更新的模型是IdentityRole 以下是观点: @model AG.SharedServices.DTO.IdentityUser @{ ViewBag.Title = "Edit"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Edit</h2> @using (Html.BeginForm

所以现在我正在尝试创建一个用户管理页面。页面的主模型实际上是一个IdentityUser,但我试图从视图更新的模型是IdentityRole

以下是观点:

@model AG.SharedServices.DTO.IdentityUser

@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>IdentityUser</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Id)

        <div class="form-group">
            @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <ul>
                @foreach (var role in TempData["Roles"] as IEnumerable<AG.SharedServices.DTO.IdentityRole>)
                {
                    <li>
                        <input name="@role.Name" type="checkbox" value="@role.Selected" />@role.Name
                    </li>
                }
            </ul>

        </div>


        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
我们要通过的模型是,IdentityRole,看起来像这样:

using Microsoft.AspNet.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AG.SharedServices.DTO
{
    public class IdentityRole : IRole
    {
        /// <summary>
        /// Default constructor for Role 
        /// </summary>
        public IdentityRole()
        {
            Id = Guid.NewGuid().ToString();
        }
        /// <summary>
        /// Constructor that takes names as argument 
        /// </summary>
        /// <param name="name"></param>
        public IdentityRole(string name)
            : this()
        {
            Name = name;
        }

        public IdentityRole(string name, string id)
        {
            Name = name;
            Id = id;
        }

        /// <summary>
        /// Role ID
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// Role name
        /// </summary>
        public string Name { get; set; }

        public bool Selected { get; set; }
    }
}
使用Microsoft.AspNet.Identity;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间AG.SharedServices.DTO
{
公共类标识role:IRole
{
/// 
///角色的默认构造函数
/// 
公共身份证()
{
Id=Guid.NewGuid().ToString();
}
/// 
///以名称作为参数的构造函数
/// 
/// 
公共标识符(字符串名称)
:此()
{
名称=名称;
}
公共标识符(字符串名称、字符串id)
{
名称=名称;
Id=Id;
}
/// 
///角色ID
/// 
公共字符串Id{get;set;}
/// 
///角色名
/// 
公共字符串名称{get;set;}
已选择公共布尔值{get;set;}
}
}
有人知道如何在视图中使用foreach循环来传递IdentityRoles并更改角色的选定值,以便将用户分配给角色吗


谢谢

您应该在动作中使用类似UserIdentityModel的角色数组

public class UserIdentityModel
{
   ...

   public IList<IdentityRole> Roles { get; set; }
}
public类UserIdentityModel
{
...
公共IList角色{get;set;}
}
并在视图上创建角色列表

   @model UserIdentityModel
   ...
   <ul>
       @for (var i = 0; i < Model.Roles.Count; i++)
       {
          <li>
             <input name="@("Roles[" + i + "].Selected")" type="checkbox" value="@(Model.Roles[i].Selected)" />@Model.Roles[i].Name
             <input type="hidden" name="@("Roles[" + i + "].Name")" value="@(Model.Roles[i].Name)">
             <input type="hidden" name="@("Roles[" + i + "].Id")" value="@(Model.Roles[i].Id)">
          </li>
       }
    </ul>
@model UserIdentityModel
...
    @对于(var i=0;i @Model.Roles[i].Name }
在post操作中,您将收到包含角色集合的UserIdentityModel

public ActionResult Edit(string id)
{
   var user = UserManager.FindById(id);
   var model = new UserIdentityModel();
   ///Fill all fields of the model      
   return View(model);
}

// POST: UserAdmin/Edit/5
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(UserIdentityModel model)
{
   ...
   foreach(var role in model.Roles)
   {
      ...
   }
公共操作结果编辑(字符串id)
{
var user=UserManager.FindById(id);
var model=new UserIdentityModel();
///填充模型的所有字段
返回视图(模型);
}
//帖子:UserAdmin/Edit/5
[HttpPost,ActionName(“编辑”)]
[ValidateAntiForgeryToken]
公共异步任务编辑(UserIdentityModel模型)
{
...
foreach(model.Roles中的var角色)
{
...
}

您没有在视图中的任何位置使用
CheckBoxFor()
(查看您的问题标题)。您只需创建一个chekbox集合,其名称与您的模型完全没有关系,因此它们将永远不会绑定到任何对象。请使用表示您需要编辑的内容的视图模型。请参阅最新的编辑,我添加了我们尝试在
CheckBoxFor()中使用的代码
没有区别-您没有生成与您的模型相关的输入。而且在任何情况下,您都不能使用
foreach
循环(它必须是
for
循环),这实际上就是我们最终要做的!谢谢您,回答得很好!生成html的糟糕方式-:)使用
@html.HiddenFor(m=>m.Roles[i].Name)
。但如果OP真的为一个集合生成了大量隐藏的输入,那么它只会降低性能,并容易受到套印攻击。
public ActionResult Edit(string id)
{
   var user = UserManager.FindById(id);
   var model = new UserIdentityModel();
   ///Fill all fields of the model      
   return View(model);
}

// POST: UserAdmin/Edit/5
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(UserIdentityModel model)
{
   ...
   foreach(var role in model.Roles)
   {
      ...
   }