【问题标题】:Value cannot be null. Parameter name: items (in Dropdown List) ASP.NET MVC5值不能为空。参数名称:项目(在下拉列表中)ASP.NET MVC5
【发布时间】:2018-08-22 10:32:21
【问题描述】:

我的代码有问题。我正在使用 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 

我尝试了不同的解决方案来解决它,但没有任何效果,有人可以帮忙或建议吗?

【问题讨论】:

  • 确保 var roles = _context.Roles.ToList();正在返回所有角色的值。
  • 不,它不会复制任何东西,这是我的代码中的一个特定问题,而不是关于 NullReferenceException 含义的一般问题,我该如何解决?

标签: c# asp.net asp.net-mvc-5


【解决方案1】:

您不能将&lt;select&gt; 元素绑定到复杂对象(这就是Role),并且当您提交表单时,ModelState 无效(您尝试绑定@987654326 的选定Name 属性@ to 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>

这将解决与Role 相关的无效ModelState 问题,但如果您确实因为其他ModelState 问题需要返回视图,那么您必须先重新填充集合,然后再返回视图

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

【讨论】:

  • 我正在尝试您的解决方案,当我将 (SelectListItem) 添加到 RegisterViewModel 时,出现此错误,(找不到类型或命名空间名称“SelectListItem”(您是否缺少 using 指令或一个程序集引用?)所以我导入了命名空间(System.Web.Mvc)然后我得到了新的错误(错误 1 ​​'CompareAttribute' 是 'System.ComponentModel.DataAnnotations.CompareAttribute' 和 'System.Web.Mvc. CompareAttribute') ,(错误 2 找不到类型或命名空间名称“Compare”(您是否缺少 using 指令或程序集引用?))
  • 现在出现新错误(错误 1 ​​无法将类型“System.Web.Mvc.SelectList”隐式转换为“System.Collections.Generic.IEnumerable”。存在显式转换(您是否缺少演员表?))
  • 您使用了错误的参考文献。您需要同时包含 System.Web.MvcSystem.ComponentModel.DataAnnotations 但使用完全限定名称或别名 - 请参阅 this answer
  • “视图模型不应包含数据模型”是什么意思?需要更多澄清才能成为有用的答案。
【解决方案2】:

好的,我遇到了同样的问题,除非我自己想出来,否则此页面上的解决方案都没有帮助我。

在发布表单时,

当我们使用时

If( ModelState.IsValid())
{
//post here


}

return view (model);

实际上我们并没有在 POST 方法中初始化下拉列表中的项目。这就是为什么抛出这个 nullaugumentexception 的原因。我们只需要在 post 方法中初始化模型中的项目列表,就像我们在调用表单时所做的那样,这样它就可以在发布期间的模型无效时初始化列表,然后 将模型放入return语句中。

【讨论】:

  • 你有不同的问题,我们正在初始化列表,这是常识
  • @amal50 ,您可能有不同的问题。但我的是这个..我还必须在 post 方法中初始化列表..这样如果模型无效,则必须再次初始化列表以显示 agian
【解决方案3】:

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

模型(部分)

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

查看

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

控制器(获取)

 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
        };

【讨论】:

    【解决方案4】:

    我个人会在您的控制器中创建选择列表并将其传递给模型,编写类似

      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" })
    

    这种方法/语法对我有用,但我不确定它是否是“最佳实践”

    【讨论】:

    • 它给了我新的错误,(传递到字典中的模型项的类型是'System.Collections.Generic.List`1[System.Web.Mvc.SelectListItem]',但是这个字典需要'TransactionsSystem.Models.RegisterViewModel' 类型的模型项。)
    【解决方案5】:

    确保在返回视图之前将列表添加到模型中,否则会出现此错误。 示例:

    cshtml:

    @model DelegatePortal.ViewModels.ImpersonateVendorViewModel
    
    
    @using (Html.BeginForm("ImpersonateVendor", "Admin", FormMethod.Post))
    {
        @Html.DropDownListFor(model => model.Id, new SelectList(Model.Vendors, "Id", "Name"), "Choose a vendor", new { @class = "form-control form-control-sm " })
    }
    

    控制器:

    // GET: /Admin/ImpersonateVendor
        public ActionResult ImpersonateVendor()
        {
            ImpersonateVendorViewModel model = new ImpersonateVendorViewModel();
            var vendors = (from c in db.Vendors
                            select c).ToList();
            model.Vendors = vendors; --> add list here
            return View(model);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 2020-09-25
      • 1970-01-01
      相关资源
      最近更新 更多