【问题标题】:Why do I get "The parameters dictionary contains a null entry for parameter" exception?为什么会出现“参数字典包含参数的空条目”异常?
【发布时间】:2018-02-10 10:14:26
【问题描述】:

当我尝试回发绑定模型以进行更新时出现此错误:

参数字典包含“EtlGui.控制器.用户控制器'。可选参数必须是引用类型、可空类型或声明为可选参数。 参数名称:参数

这是我的操作:

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>

【问题讨论】:

  • 因为您没有在表单中提交 id 的值(请花一些时间正确格式化您的代码,以便其可读)
  • 不应该在那里吗?因为我已经绑定在 GET 请求中
  • 如果您生成了正确的视图(使用 HtmlHelper 方法,包括 @using(Html.BeginForm()) { ... (但从您的代码中可以看出,您尽一切可能确保模型绑定不起作用))
  • 谢谢..它有效!!

标签: asp.net-mvc


【解决方案1】:

您的表单不包含 id 属性的值,因此不会将任何内容发布到控制器。您可以为其包含一个输入,但默认情况下,当您使用BeginForm 方法时,GET 方法中的参数将添加到表单action 属性中。删除您的手册 &lt;form&gt; 元素并将其替换为

@using (Html.BeginForm())
{
    ....
}

生成的 html 将包含 action="/yourController/EditUser/X",其中 X 是 GET 方法中 id 的值,并将绑定到 POST 方法中的 id 参数。

您的代码还有多个其他问题会导致模型绑定失败。删除所有手动 html 并使用强类型 HtmlHelper 方法正确生成 html 以进行 2 向模型绑定和客户端验证。 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() 为集合生成表单控件。在/Views/Shared/EditorTemplates 中创建一个名为RoleCheckbox.cshtmlEditorTemplate(以匹配类名),代码如下

@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.EditorFor(m => m.Roles)

这将为集合中的每个项目正确生成 html。

您还可以考虑使用[Remote] 属性来检查username 在客户端验证中是否唯一 - 请参阅How to: Implement Remote Validation in ASP.NET MVC

【讨论】:

  • 我试图进入它不幸的是远程验证没有触发
猜你喜欢
  • 2019-09-15
  • 1970-01-01
  • 2017-05-12
  • 2018-01-21
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
相关资源
最近更新 更多