当我尝试回发我的绑定模型以进行更新时,我收到此错误:
参数字典包含参数' id'的空条目。非可空类型的System.Int32' for method' System.Web.Mvc.ActionResult EditUser(Int32,EtlGui.ViewModels.UsersEdit)' in' EtlGui.Controllers.UsersController'。可选参数必须是引用类型,可空类型,或者声明为可选参数。 参数名称:参数
以下是我的行动:
public ActionResult EditUser(int id)
{
User user = Database.Session.Load<User>(id);
if (user == null)
return HttpNotFound();
return View(new UsersEdit
{
username = user.username,
email = user.email,
Roles = Database.Session.Query<Role>().AsEnumerable().Select(role => new RoleCheckbox
{
id = role.id,
ischecked = user.Roles.Contains(role),
name = role.name
}).ToList()
});
}
[HttpPost,ValidateAntiForgeryToken]
public ActionResult EditUser(int id,UsersEdit edit )
{
var user = Database.Session.Load<User>(id);
if (user == null)
return HttpNotFound();
syncRole(edit.Roles,user.Roles);
if (Database.Session.Query<User>().Any(u => u.username == edit.username && u.id != id))
ModelState.AddModelError("username","username must be unique");
if (!ModelState.IsValid)
return View(edit);
user.username = edit.username;
user.email = edit.email;
Database.Session.Update(user);
return RedirectToAction("UsersServices");
}
和我的观点:
@model EtlGui.ViewModels.UsersEdit
....
<h2 class="heading">Edit User @Model.username</h2>
<form action="@Url.Action("EditUser")" method="POST" class="login">
@Html.AntiForgeryToken()
@Html.ValidationSummary()
....
<div class="col-lg-3 label">user name :</div>
<div class="col-lg-4">
<input type="text" name="username" class="form-control" value="@Model.username">
</div>
<div class="col-lg-3 label">email :</div>
<div class="col-lg-4">
<input type="text" name="email" class="form-control" value="@Model.email">
</div>
<div class="col-lg-3 label">password :</div>
<div class="col-lg-4">
<input type="password" name="password" class="form-control">
</div>
<h1 class="heading">select Roles</h1>
@Html.Partial("_RoleEditor", Model.Roles)
<button type="submit" class="btn darkblue-btn">Update User</button>
</form>
答案 0 :(得分:1)
您的表单不包含id
属性的值,因此没有任何内容发布到控制器。您可以为其包含输入,但默认情况下,当您使用action
方法时,GET方法中的参数将添加到表单BeginForm
属性中。删除手册<form>
元素并将其替换为
@using (Html.BeginForm())
{
....
}
生成的html将包含action="/yourController/EditUser/X"
,其中X是GET方法中id
的值,并将绑定到POST方法中的id
参数。
您的代码还有许多其他问题会导致模型绑定失败。删除所有手动html并使用强类型HtmlHelper
方法正确生成用于双向模型绑定和客户端验证的html。 username
属性的典型代码是
@Html.LabelFor(m => m.username)
// or @Html.LabelFor(m => m.username, "user name :") if you have not applied a [Display] attribute
@Html.TextBoxFor(m => m.username, new { @class="form-control" })
@Html.ValidationMessageFor(username)
并且不要使用@Html.Partial()
为集合生成表单控件。在名为EditorTemplate
的{{1}}中创建/Views/Shared/EditorTemplates
(以匹配类名),并使用以下代码
RoleCheckbox.cshtml
并在主视图中,将@model RoleCheckbox
@Html.HiddenFor(m => m.id)
@Html.HiddenFor(m => m.name)
@Html.LabelFor(m => m.ischecked, Model.name)
@Html.CheckBoxFor(m => m.ischecked)
@Html.ValidationMessageFor(m => m.ischecked)
替换为
@Html.Partial("_RoleEditor", Model.Roles)
将正确生成集合中每个项目的html。
您还可以考虑使用@Html.EditorFor(m => m.Roles)
属性检查[Remote]
在客户端验证方面是否唯一 - 请参阅How to: Implement Remote Validation in ASP.NET MVC