参数未从 Ajax 调用填充(尝试了一切)

Posted

技术标签:

【中文标题】参数未从 Ajax 调用填充(尝试了一切)【英文标题】:Parameter not populating from Ajax call (Tried everything) 【发布时间】:2021-06-22 13:27:50 【问题描述】:

大家好。

我有一个简单的Ajax 电话。简单来说,它从密码字段中读取密码,将其填充到变量中,然后将其发送到我的强度检查控制器。因此,一切都运行良好,ajax 调用使其进入 StregthCheck ActionResult,并且 ajax 成功部分被 hunky-dory 触发。但是,我的 StrengthCheck actionResult 中的参数 Password 不会填充从我的 ajax 调用发送的密码。我真的相信我已经尝试了所有方法,无论是可能的解决方案还是高级调试技巧,任何输入都将不胜感激。

提前非常感谢,希望这个问题尽可能简单。

脚本

<script>

    $(document).ready(function () 
        $("#Password").change(function () 
            debugger
            var password = $("#Password").val();

            $.ajax(
                url: '@Url.Action("StrengthCheck", "Login")',
                data:  Password: password ,
                dataType:'json',
                type: 'POST',
                success: function (result) 
                    $("#PasswordStrength").val(result);
                    if (result.PasswordStrength != "Blank" && result) 
                        console.log(result);
                        var lblStatus = document.getElementById("PasswordStrength");
                        lblStatus.style.width = result + "%";
                        switch (result)
                            
                                case "20":
                                    $("#PasswordStrength").removeClass("progress-bar-success").addClass("progress-bar-warning");
                                    break;
                                case "40":
                                    $("#PasswordStrength").removeClass("progress-bar-success").addClass("progress-bar-warning");
                                    break;
                                case "60":
                                    $("#PasswordStrength").removeClass("progress-bar-warning").addClass("progress-bar-success");
                                    break;
                                case "80":
                                    $("#PasswordStrength").removeClass("progress-bar-warning").addClass("progress-bar-success");
                                    break;
                                case "100":
                                    $("#PasswordStrength").removeClass("progress-bar-warning").addClass("progress-bar-success");
                                    break;
                            

                        


                    ,
                error: function (jqxhr, textStatus, errorThrown) 
                    console.log(jqxhr);
                    console.log(textStatus);
                    console.log(errorThrown);

                ,
                    async: true,
                    processData: false

            );

        )



    );



</script>

登录控制器

        [AllowAnonymous]
        [HttpPost]
        public JsonResult StrengthCheck(PhysiotherapyDAL.ViewModels.PasswordResetViewModel data)
        
            #region password strength
            PasswordScore passwordStrengthScore = PasswordAdvisor.CheckStrength(data.Password); 

            switch (passwordStrengthScore)
            
                case PasswordScore.Blank:
                    data.PasswordStrength = 0;
                    return Json(JsonConvert.SerializeObject(data.PasswordStrength), JsonRequestBehavior.AllowGet);
                case PasswordScore.VeryWeak:
                    data.PasswordStrength = 20;
                    return Json(JsonConvert.SerializeObject(data.PasswordStrength), JsonRequestBehavior.AllowGet);
                case PasswordScore.Weak:
                    data.PasswordStrength = 40;
                    return Json(JsonConvert.SerializeObject(data.PasswordStrength), JsonRequestBehavior.AllowGet);
                case PasswordScore.Medium:
                    data.PasswordStrength = 60;
                    return Json(JsonConvert.SerializeObject(data.PasswordStrength), JsonRequestBehavior.AllowGet);
                case PasswordScore.Strong:
                    data.PasswordStrength = 80;
                    return Json(JsonConvert.SerializeObject(data.PasswordStrength), JsonRequestBehavior.AllowGet);
                case PasswordScore.VeryStrong:
                    data.PasswordStrength = 100;
                    return Json(JsonConvert.SerializeObject(data.PasswordStrength), JsonRequestBehavior.AllowGet);
                default:
                    break;
            
            #endregion
            data.PasswordStrength = 0;
            return Json(JsonConvert.SerializeObject(data.PasswordStrength), JsonRequestBehavior.AllowGet);
        

密码重置视图模型

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PhysiotherapyDAL.ViewModels

   public class PasswordResetViewModel
    

        [Required(ErrorMessage = "Password required")]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password  get; set; 

        [Display(Name = "Confirm Password")]
        [Required(ErrorMessage = "Confirm password required")]
        [DataType(DataType.Password)]
        [Compare("Password", ErrorMessage = "The two passwords do not match. Please ensure they match.")]
        public string ConfirmPassword  get; set; 

        public string ResetCode  get; set; 

        public string UserID  get; set; 
        
        public bool success  get; set; 

        public int PasswordStrength  get; set; 

    


这是 chrome 调试的屏幕截图,显示了整个 ajax 调用过程中的数据填充情况 Screenshot of chrome debugging

【问题讨论】:

只是为了咯咯笑,尝试不同的名称,例如string thePassworddata: thePassword : password ,(有 something 告诉我“密码”参数是保留名称并由 mvc 以不同方式处理) 您的编辑 StrengthCheck actionResult 有点奇怪 - 您的 result 中没有密码 另外,既然你的结果只是一个int,为什么不直接返回ActionResult int呢? 如果问题出在返回值上,试试return Json(new PasswordStrength , JsonRequestBehavior.AllowGet) - return Json(... 为你序列化结果,所以你序列化了两次 也许题外话:if (result.PasswordStrength != "Blank" &amp;&amp; result) 会出错,如果 result==null js 中的 &amp;&amp; 是从左到右的 - 需要是 if (result &amp;&amp; result.PasswordStrength != "Blank") 放入控制台的示例:var x = null; if (x.test &amp;&amp; x) console.log("x") 【参考方案1】:

如果没有任何效果,则使用查询字符串进行测试,为此更改您的网址,如下所示

 $(document).ready(function () 
    $("#Password").change(function () 
        debugger
        var password = $("#Password").val();

        $.ajax(
            url: '/Login/StrengthCheck?Password='+password ,
            data: ,
            dataType:'json',
          ----
         )

方法二。

 $(document).ready(function () 
        $("#Password").change(function () 
            debugger
            var password = $("#Password").val();
            var data=
                       "password" :password ,
                      
           

            $.ajax(
                url: '/Login/StrengthCheck' ,
                data:Json.Stringify(data),
                dataType:'json',
              ----
             )

模型绑定器:- https://www.sharpencode.com/article/MVC/model-binders

【讨论】:

哇,非常感谢!当然这不是最佳实践吗?像在专业环境中一样离开它可以吗? 不幸的是,同样的问题出现了,数据模型返回一个空密码。【参考方案2】:

HttpPost 可以从 QueryString 和请求正文中接收参数。 默认情况下,在查询字符串中搜索原始类型,其中复杂类型被视为在正文中。

您的方法被定义为从查询字符串而不是正文接收密码。这就是它保持空白的原因。 你有两种方法可以解决这个问题。

您更改了 ajax 调用,以便密码在查询字符串中。 您更改方法以接收复杂模型并保留您的 ajax
public class Model 
  public string Password get; set;

【讨论】:

嗨,Kevin,感谢您让这变得非常可教。你教会了我一些新东西。然而,不幸的是,在尝试简化问题之前,我实际上有一个模型表现得像一个复杂类型,在那里我遇到了同样的问题。我已经编辑了问题的代码,请重新分析它并告诉我它是正确的。不幸的是,它仍然无法正常工作。 @MatthewLeslie 我看到了一些问题,例如 ConfirmPassword 是必需的,但在 ajax 中不可见(但您正在测试并且可能已经改变)。在您的方法中,您还可以检查 ModelState.IsValid 以查看模型是否已正确解析。 ModelState 还应该说明模型错误的原因 凯文你好,所以 ajax 实际上是在 a.change 函数上执行的,所以在我想测量模型状态之前它就已经关闭了。当按下按钮时,我测量模型状态并确保确认密码在那里。 @MatthewLeslie 好的,我们在这里谈论不同的事情。在服务器端检查模型状态。它是控制器方法中的一个对象,它提供有关已解析模型的信息以及它为何为空或失败的原因。 好的,我明白了,谢谢你的洞察力,我现在要用它来测试。我以前只使用 ModelState 来确保填充了我的必填字段等。

以上是关于参数未从 Ajax 调用填充(尝试了一切)的主要内容,如果未能解决你的问题,请参考以下文章

Ajax / PHP:调用正常,但未从 PHP 发出警报结果

Ajax 调用未从 ActiveRecord 返回最新数据

JqxCombo 值未从 ajax 结果设置 - Vue.js

C# Web Api 调用未从 jquery 调用

Ajax 调用未填充表

ModelChoiceField 给出“选择一个有效的选择”,用 ajax 调用填充选择