值不能为空。 参数名称:项目(在下拉列表)ASP.NET MVC5 值不能为空。 参数名称:项

2019-05-12 10:26发布

我有问题,在我的代码,我使用它自带的MVC5登记表,我添加字段,“角色”的下拉列表,同时创建一个新用户分配一个角色给用户。 像下面的图像中

现在,为了做到这一点,我修改了“RegisterViewModel”,并添加以下属性

        public IdentityRole Role { get; set; }

        [Required]
        [Display(Name = "Roles List")]
        public IEnumerable<IdentityRole> RolesList { get; set; }

在“的AccountController”,我改变注册动作,即获取报名表,变成这个样子:

// GET: /Account/Register
        [AllowAnonymous]
        public ActionResult Register()
        {

            var _context = new ApplicationDbContext();
            var roles = _context.Roles.ToList();

            var viewModel = new RegisterViewModel
            {
                RolesList = roles
            };
            return View(viewModel);

        }

在视图“Register.cshtml”我加入这个下拉列表加载视图中的角色以及张贴作用控制器

<div class="form-group">
        @Html.LabelFor(m => m.Role.Id, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.DropDownListFor(m => m.Role, new SelectList(Model.RolesList, "Name", "Name"), "Select Role", new { @class = "form-control" })
        </div>
    </div>

在注册控制器,即邮政登记表,我加入此

// POST: /Account/Register
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser() { UserName = model.UserName , centerName = model.centerName };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    var role = new IdentityRole(model.Role.Name);

                    //I added this line to store the user and its roles in AspNetUserRoles table
                    await UserManager.AddToRoleAsync(user.Id, role.Name);

                    await SignInAsync(user, isPersistent: false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    AddErrors(result);
                }
            }

现在,当尝试注册用户和发布形式,我得到以下错误:

Server Error in '/' Application.

Value cannot be null.
Parameter name: items

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: items

Source Error: 


Line 41:         @Html.LabelFor(m => m.Role.Name, new { @class = "col-md-2 control-label" })
Line 42:         <div class="col-md-10">
Line 43:             @Html.DropDownListFor(m => m.Role, new SelectList(Model.RolesList, "Name", "Name"), "Select Role", new { @class = "form-control" })
Line 44:         </div>
Line 45:     </div>

Source File: c:..\TransactionsSystem\Views\Account\Register.cshtml    Line: 43 

我尝试了不同的解决方案来解决这个问题,但是毫无效果,任何人都请帮助或建议?

Answer 1:

你可以不绑定<select>元素的复杂对象(这是什么Role是),当您提交表单, ModelState是(你想选择的绑定无效Name的属性RolesList到TYPEOF IdentityRole )。 然后,返回查看,但没有重新填充RolesList属性,因此其null (因此错误)。

查看模型不应该包含的数据模型,并查看模式应该是

public class RegisterViewModel
{
    ....
    [Required(ErrorMessage = "Please select a role")]
    public string Role { get; set; }
    public IEnumerable<SelectListItem> RoleList { get; set; }
}

和在GET方法

var roles = _context.Roles.Select(r => r.Name);
var viewModel = new RegisterViewModel
{
    RolesList = new SelectList(roles)
};
return View(viewModel);

并在视图

@Html.LabelFor(m => m.Role, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
    @Html.DropDownListFor(m => m.Role, Model.RolesList, "Select Role", new { @class = "form-control" })
</div>

这将解决无效ModelState有关问题Role ,但如果你确实需要返回,因为其他观点ModelState问题,那么您必须先返回视图之前重新填充集合

if (!ModelState.IsValid)
{
    var roles = _context.Roles.Select(r => r.Name);
    model.RolesList = new SelectList(roles);
    return View(model);
}
.... // save and redirect


Answer 2:

个人而言,我会在你的控制器创建选择列表,并把它传递给模型,写东西喜欢

  var RolesList = new List<SelectListItem>
            {
                new SelectListItem { Value = string.Empty, Text = "Please select a Role..." }
            };

   RolesList.AddRange(roles.Select(t => new SelectListItem
            {
                Text = t.role,
                Value = t.Id.ToString()
            }));` 

然后添加到您的模型,在模型中就可以使用

@Html.DropDownListFor(m => m.Role, Model.RoleList, new { @class = "form-control" })

这种方法/语法为我工作,我不知道这是否是“最佳实践”,虽然



Answer 3:

在MVC5为我工作的编辑现有用户的解决方案

模型(的一部分)

public IEnumerable<string> Roles { get; set; }

视图

@Html.DropDownListFor(model => model.UserRole, new SelectList(Model.Roles, Model.UserRole), new { @class = "form-control" })

控制器(GET)

 var model = new EditUserViewModel()
        {
            UserName = user.UserName,
            Email = user.Email,
            IsEnabled = user.IsEnabled,
            Id = user.Id,
            PhoneNumber = user.PhoneNumber,
            UserRole = userRoleName,

            // a list of all roles
            Roles = from r in RoleManager.Roles orderby r.Name select r.Name
        };


Answer 4:

这个答案再次编辑,现在是可以正常使用

我想出了一个新的解决方案,我不需要做出所需要的名单,我只能创造财产ROLENAME并使其需要。

在RegisterViewModel,我只加这行到RegisterViewModel:

    [Display(Name = "Roles List")]
    public List<IdentityRole> RolesList { get; set; }

    [Required (ErrorMessage = "Please Select the Role")]
    public string RoleName { get; set; } 

鉴于我犯了这样的下拉列表

 <div class="form-group"> @Html.LabelFor(m => m.RoleName, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.DropDownListFor(m => m.RoleName, new SelectList(Model.RolesList, "Name", "Name"), "Select Role", new { @class = "form-control" }) </div> </div> 

在AccountController.CS,寄存器操作是这样的:

[AllowAnonymous]
        public ActionResult Register()
        {
            var _context = new ApplicationDbContext();
            var roles = _context.Roles.ToList();

            var viewModel = new RegisterViewModel
            {
                RolesList = roles
            };
            return View(viewModel);           
        }

而张贴的形式注册的动作,我做了这样的:

public async Task<ActionResult> Register(RegisterViewModel model)
        {

            if (ModelState.IsValid)
            {
                var user = new ApplicationUser() { UserName = model.UserName , centerName = model.centerName };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    await UserManager.AddToRoleAsync(user.Id, model.RoleName);

                    await SignInAsync(user, isPersistent: false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    AddErrors(result);
                }
            }

            // If we got this far, something failed, redisplay form
            var _context = new ApplicationDbContext();
            var roles = _context.Roles.ToList();
            model.RolesList = roles;
            return View(model);
            }


文章来源: Value cannot be null. Parameter name: items (in Dropdown List) ASP.NET MVC5