在 MVC6 中获取清单数据 post

Getting CheckList data in MVC6 post

我在 MVC6(使用 EF7)中做用户角色,我想我只是遗漏了一些东西,但是在用于定义用户角色的表单上,我在 posted back 模型中什么也得不到到控制器

这是我的模特

public class UserRoleItem
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public IdentityUserRole<int> userRole { get; set; }
    public bool HasRole { get; set; }
}

public class UsersRolesViewModel
{
    public int UserId { get; set; }
    public string FullName { get; internal set; }

    public List<UserRoleItem> UserRoles;
}

这是视图

@model Skill.ViewModels.Manage.UsersRolesViewModel
<br />
<h3>Set Roles for user - @Model.FullName</h3>
<form asp-action="ChangeUsersRoles" >
    <div class="form-horizontal">
        <hr />
        <input type="hidden" asp-for="UserId" />

        @foreach (var userRole in Model.UserRoles)
        {
            <input type="hidden" asp-for="@userRole.Id" />
            <div class="form-group">
                <div class="inline-block col-md-8">
                    <span class="col-md-1" align="center">
                        <input type="checkbox" asp-for="@userRole.HasRole" />
                    </span>
                    <div class="col-md-7">
                        @userRole.Name (@userRole.Description)
                    </div>
                </div>
            </div>
        }
        <hr />
        <div class="form-group">
            <div class="col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>

这是控制器

// GET: Users/ChangeUserRoles/5
public async Task<IActionResult> ChangeUserRoles(int? id)
{
    if (id == null)
    {
        return HttpNotFound();
    }

    var model = new UsersRolesViewModel();
    ApplicationUser appUser = await _context.ApplicationUsers.SingleAsync(m => m.Id == id);
    if (appUser == null)
    {
        return HttpNotFound();
    }
    else
    {
        model.UserId = (int)id;
        model.FullName = appUser.FullName;
        var some = from r in _context.Roles
                   from ur in _context.UserRoles
                   .Where(inner => r.Id == inner.RoleId && inner.UserId == id)
                   .DefaultIfEmpty()
                   select new UserRoleItem
                   {
                       Id = (int)r.Id,
                       Name = r.Name,
                       Description = r.NormalizedName,
                       userRole = ur, // this is needed else it has a hissy fit
                       HasRole = (ur != null)
                   };
        // get all of the Roles and then also link to the ones the user currently has
        model.UserRoles = (some).ToList();
    }
    return View(model);
}

// POST: Users/ChangeUserRoles/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ChangeUserRoles([Bind(include:"UserId,UserRoles")]UsersRolesViewModel userModel)
{
    if (ModelState.IsValid)
    {
        // update based on the changes

        // return RedirectToAction("Edit", new { userModel.UserId });
    }
    return View(userModel);
}

因此,当我在保存时返回 post 时,UserRoles 列表为空,所以我想我只是遗漏了一个明显的东西?

还有一个小问题是EF Linq 语句。如果我删除

userRole = ur,

来自 Linq 查询的 Select 部分的语句,系统有一个合适的并说我的架构已过时(事实并非如此)。我认为这是由于我正在测试外部连接值

的以下语句所致
HasRole = (ur != null)

虽然这看起来非常合理,并且如果在测试 null(或不)之前使用 ur 变量就可以工作

输入这个问题后 - 我进一步调查了这个问题,发现我可以使用 EditorTemplate 做我需要的事情 所以我在我的 Users View 文件夹下创建了 EditorTemplate 文件夹,因为它是一个 UsersController,然后添加了以下 UserRoleItem.cshtml 文件

@model UserRoleItem

<input type="hidden" asp-for="Id" />
<div class="form-group">
    <div class="inline-block col-md-8">
        <span class="col-md-1" align="center">
            <input type="checkbox" asp-for="HasRole" />
        </span>
        <div class="col-md-7">
            @Model.Name (@Model.Description)
        </div>
    </div>
</div>

然后我将视图(称为 ChangeUsersRole.cshtml)更改为

@model Skill.ViewModels.Manage.UsersRolesViewModel

<br />
<h3>Set Roles for user - @Model.FullName</h3>
<hr />
<form asp-action="ChangeUsersRoles">
    <div class="form-horizontal">
        <input type="hidden" asp-for="UserId" />
        @Html.EditorFor(m => m.UserRoles)
        <hr />
        <div class="form-group">
            <div class="col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>

另请注意:我尝试使用新格式

<input asp-for="UserRoles" />

而不是视图中的这一行

@Html.EditorFor(m => m.UserRoles)

但它没有按预期工作。再说一次,也许我仍然做错了什么 - 或者该功能可能还没有工作?