【问题标题】:AJAX AntiForgery Token not calling controller methodAJAX AntiForgery Token 不调用控制器方法
【发布时间】:2016-05-06 16:23:29
【问题描述】:

我正在努力使用 [ValidateAntiForgeryToken] 属性调用我的控制器方法。

我的 cshtml/js 代码:

    var wizardRegisterJsonRequest = {
        Email: email,
        Password: password,
        ConfirmPassword: confirmPassword,
        Name: name
    };


    $.ajax({
        type: 'POST',
        dataType: "html",
        url: 'http://localhost:50209/GetAllFonts/WizardRegister',
        data: AddAntiForgeryToken(wizardRegisterJsonRequest),
        beforeSend: function () {
            $('#create_account_form').data('busy', true);
            $('#create_account_busy').show();
        },
        success: function (data) {
            if (data.Success === true) {
                // all good here
            }

            $('#create_account_validation_summary').text(data.Message);
            $('#create_account_validation_summary').show();
        },
        complete: function () {
            $('#create_account_form').data('busy', false);
            $('#create_account_busy').hide();
        }
    });

    AddAntiForgeryToken = function (data) {
            alert("adding anti forgery");
          data.__RequestVerificationToken = $('#anti_forgery_token').val();
          return data;
    };

控制器代码:

    [ValidateAntiForgeryToken]
    [HttpPost]
    public JsonResult WizardRegister(User usrDetails)
    //public JsonResult WizardLogOn(User usr)
    {
        // string test = ""; // this method WizardRegister is not getting called
    }

用户模型:

public class User
{
    public string Email { get; set; }
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
    public string __RequestVerificationToken { get; set; }
}

我不确定用户模型中是否需要 __RequestVerificationToken。我是第一次使用 AntiForgery。

请让我知道我哪里出错了......

谢谢, 罗汉。

更新:

查看/表单代码:

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "create_account_form" }))
{
    @Html.AntiForgeryToken()
    <fieldset>
        <div class="input-fixed">
            <span class="mandatory_wizard">* </span>
            <input type="text" id="registrName" name="registrName" value="rohan" class="name" placeholder="Name">
        </div>
        <div class="input-fixed">
            <span class="mandatory_wizard">* </span>
            <input type="text" id="registrEmail" name="registrEmail" class="email" value="rohanskosht@gmail.com" placeholder="Email">
        </div>
        <div class="input-fixed">
            <span class="mandatory_wizard">&nbsp; </span>
            <input type="text" class="phone" placeholder="Phone Number">
        </div>
        <div class="input-fixed">
            <span class="mandatory_wizard">* </span>
            <input type="password" id="registerPassword" name="registerPassword" value="12345678" class="password" placeholder="Password: Must be longer than 8 characters.">
        </div>
        <div class="input-fixed">
            <span class="mandatory_wizard">* </span>
            <input type="password" id="registerConfirmPassword" name="registerConfirmPassword" value="12345678" class="confirm-password" placeholder="Confirm Password">
        </div>
        <input type="submit" class="btn-modal-login" value="Create your account &gt;&gt;">
        <img id="create_account_busy" style="display: none;" src="./Launch Campaign _ Teeyoot_files/busy.gif" alt="Loading...">
    </fieldset>
}

【问题讨论】:

  • 不,您不需要在模型中包含 string __RequestVerificationToken。它失败了,因为您从未将令牌添加到您发布的数据中。检查@Html.AntiForgeryToken()` 生成的html - 它没有id="anti_forgery_token"
  • 嗨斯蒂芬,谢谢你的帮助,我在 anti_forgery_token 变量中有值......它有一些长字符串,这是令牌值......但仍然没有进入控制器方法....
  • 显示生成的 html!它没有id="anti_forgery_token"(但它确实有name="name=__RequestVerificationToken"),因此您无法使用__RequestVerificationToken = $('#anti_forgery_token').val();访问它
  • 跨度>
  • 你需要用视图代码编辑你的问题(不是在 cmets 中你甚至不格式化就无法阅读)并显示视图代码(不是它生成的 html)

标签: json ajax asp.net-mvc-4 controller antiforgerytoken


【解决方案1】:

@Html.AntiForgeryToken() 使用name="__RequestVerificationToken" 生成隐藏输入。 (它没有id 属性,所以$('#anti_forgery_token').val(); 将返回未定义。

您可以使用

访问该值
var token= $('[name=__RequestVerificationToken]').val();

但是,我强烈建议您使用 HtmlHelper 方法(@Html.TextBoxFor(m =&gt; m.Name)@Html.PasswordFor(m =&gt; m.Password) 等)为您的属性生成输入,而不是生成手动 html,然后您可以简单地使用

data: $('form').serialize()

在 ajax 调用中(然后您可以删除大部分脚本)。您也不应该对 url 进行硬编码(一旦将其投入生产,它就会失败)。您的脚本只需

$.ajax({
    type: 'POST',
    dataType: "html",
    url: '@Url.Action("WizardRegister", "GetAllFonts")', 
    data: $('form').serialize(),
    beforeSend: function () {
        ....

您还应该为每个属性添加@Html.ValidationMessageFor() 以获取客户端验证,从而不会提交无效的表单。

旁注:从您的代码中不清楚为什么要使用 ajax。如果用户正在注册,那么如果成功则您需要重定向(如果没有则显示验证错误),因此 ajax 毫无意义

【讨论】:

  • 好的,但是你有很多额外的代码要写入属性处理验证错误等(我从来不明白为什么人们想要这样做而不是标准/最佳实践)
  • 通过对您的 cmets / 反馈进行一些调整,我现在可以让这个工作...... var token= $('[name=__RequestVerificationToken]').val();这工作得很好......控制器中的方法现在被调用......
猜你喜欢
  • 1970-01-01
  • 2014-06-17
  • 2021-05-22
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 2016-01-17
  • 2014-07-27
  • 1970-01-01
相关资源
最近更新 更多