1

我对 MVC 很陌生,对于一个项目,我想使用Internet 应用程序模板中现有的注册功能,除了将其移动到 jQuery 模态对话框弹出窗口中。

这是我的“新用户”按钮的点击事件,我从这个问题的答案中得到了这个想法:

$("#new-user").click(function () {

   $("#dialog-modal").empty(); // clear it out first
   $("#dialog-modal").dialog({
      height: 600,
      width: 500,
      title: "New User",
      modal: true,
      open: function (event, ui) {
         $(this).load("@Url.Action("Register")");
      },
      buttons: {
         "Add New User": function (e) {
            var $this = this;
            var form = $('form', $this);

            $.post("Account/Register", JSON.stringify($(form).serializeObject()), 
               function () {
                  $($this).dialog("close");
            });
          }
      }
   });
});

Url.Action方法如下所示:

[HttpGet]
public ActionResult Register()
{
   return View("_Register");
}

还有我的_Register.cshtml视图,它基本上是模板中的一个副本:

@model MyProject.Models.RegisterModel
@{
    Layout = null;
    ViewBag.Title = "Register";
}

<hgroup class="title">
    <h1>@ViewBag.Title.</h1>
    <h2>Create a new account.</h2>
</hgroup>

@using (Html.BeginForm()) { 

    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset>
        <legend>Registration Form</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.UserName)
                @Html.TextBoxFor(m => m.UserName)
            </li>
            <li>
                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password)
            </li>
            <li>
                @Html.LabelFor(m => m.ConfirmPassword)
                @Html.PasswordFor(m => m.ConfirmPassword)
            </li>
            <li>
                @Html.LabelFor(m => m.DisplayName)
                @Html.TextBoxFor(m => m.DisplayName)
            </li>
            <li>
                @Html.LabelFor(m => m.Email)
                @Html.TextBoxFor(m => m.Email)
            </li>
        </ol>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

现在,当单击“添加新用户”按钮时,您会看到我将表单发回帐户/注册,这是 Internet 应用程序模板的内置操作方法。这根本没有改变,仍然装饰着:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]

但是,每当我单击“添加新用户”并发布表单时,都会收到以下 500 错误消息(在 Fiddler 中看到):

所需的防伪表单字段“__RequestVerificationToken”不存在

我不确定为什么它不存在,因为 1)我的Register.cshtml视图仍然包含@Html.AntiForgeryToken()2)如果我进入该 Javascript 并查看 的值JSON.stringify($(form).serializeObject(),我看到:

"{"__RequestVerificationToken":"X3APKURbjYGUYqY2qg1VdbYl50eVNzd7TJLYKCGC-awgkK7iNH_W6bVOw7C8zHDlygP0rVO2K4TLn5KE9CYsQN8VN1DbOOV0KzMGT7xso3o1","UserName":"theUserName","Password":"thePassword","ConfirmPassword":"thePassword","DisplayName":"theDisplayName","Email":"theEmail “}”

谁能看到我做错了什么?

4

1 回答 1

2

根据我们的聊天

$(form).serialize()获取表单的控件并将它们转换为 JavaScript 对象。然后,但是调用JSON.stringify您将整个对象包装到一个字符串中。所以现在,一个潜在的有效载荷如下:

{
  "__RequestVerificationToken": "X3APKURbjYGUYqY2qg1VdbYl50eVNzd7TJLYKCGC-awgkK7iNH_W6bVOw7C8zHDlygP0rVO2K4TLn5KE9CYsQN8VN1DbOOV0KzMGT7xso3o1",
  "UserName": "theUserName",
  "Password": "thePassword",
  "ConfirmPassword": "thePassword",
  "DisplayName": "theDisplayName",
  "Email": "theEmail"
}

它将作为 6 个单独的参数接收,现在包装在一个大字符串中,现在只有 1 个参数。

建议?删除JSON.stringify和只是 AJAX 调用正常传递。然后ValidateAntiForgeryTokenAttribute可以看到__RequestVerificationToken参数进来而不是被屏蔽为字符串。

于 2013-07-02T19:07:40.877 回答