为什么我得到"参数字典包含参数"的空条目。例外?

时间:2018-02-10 10:14:27

标签: asp.net-mvc

当我尝试回发我的绑定模型以进行更新时,我收到此错误:

  

参数字典包含参数' 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>

1 个答案:

答案 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