我的代码有问题。我正在使用 MVC5 附带的注册表单,我添加了一个字段“角色”作为下拉列表,以便在创建新用户时为用户分配角色。如下图所示:
现在为了做到这一点,我修改了“RegisterViewModel”并添加了以下属性:
public IdentityRole Role { get; set; }
[Required]
[Display(Name = "Roles List")]
public IEnumerable<IdentityRole> RolesList { get; set; }
在“AccountController”中,我将获取注册表单的 Register 操作更改为如下所示:
// 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” View 中,我添加了这个下拉列表以在 View 中加载角色并将角色发布到 Controller :
<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>
在 Register Controller 中,在注册表单帖子中,我添加了这个
// 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
我尝试了不同的解决方案来解决它,但没有任何效果,任何人都可以提供帮助或建议吗?
最佳答案
您不能绑定(bind) <select>
元素到一个复杂的对象(这就是 Role
是什么),当您提交表单时,ModelState
无效(您试图将 Name
的选定 RolesList
属性绑定(bind)到 typeof IdentityRole
)。然后您返回 View ,但没有重新填充 RolesList
属性(property),所以它的null
(因此错误)。
View 模型不应该包含数据模型,而你的 View 模型应该是
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);
在 View 中
@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
相关的问题,但如果您确实需要返回 View ,因为其他 ModelState
问题,那么您必须先重新填充集合,然后再返回 View
if (!ModelState.IsValid)
{
var roles = _context.Roles.Select(r => r.Name);
model.RolesList = new SelectList(roles);
return View(model);
}
.... // save and redirect
关于c# - 值不能为空。参数名称 : items (in Dropdown List) ASP. NET MVC5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38921483/