1

我在通过 jquery 将 JSON 数据发送到我的 ASPX 页面中的 WebMethod 时遇到问题。jQuery代码是:

<script type="text/javascript">
    $(document).ready(function () {
        $("#frmLogin").validate({
            errorClass: "errorBox",
            onfocusout: false,
            rules: { 
                txtUsername: "required",
                txtPassword: "required"
            },
            messages: { 
                txtUsername: "Enter username.",
                txtPassword: "Enter password." 
            },
            submitHandler: function (form) {
                $(this).ajaxSubmit({
                    type: "POST",
                    url: "Default.aspx/Login",
                    data: '{userName: \abc\',password:\'123\'}',
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (data, textStatus, jqXHR) {
                        if (data.d) {
                            alert("OK");
                        }
                        else {
                            alert("NO");
                        }
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        alert(jqXHR.responseText);
                    },
                    complete: function (jqXHR, textStatus) {
                        alert("SUCCESS");
                    }
                });
            }
        });
    });
</script>

我不断收到的错误是“无效的 JSON 原语”。我一直在搜索,问题似乎在于数据的格式。当我更换:

data: '{userName: \abc\',password:\'123\'}',

和:

data: {},

然后一切正常。我一直在尝试许多不同的变体(在很多论坛和博客中都可以看到),例如:

data: "{userName: '" + 'abc' + "', password: '" + '123' + "'}",

data: "{userName:'abc', password:'123'}",

data: '{userName:"abc", password:"123"}',

data: '{"userName":"abc","password":"123"}',

data: '{"userName": "abc","password":"123"}',

但到目前为止没有任何效果。

我正在调用的 WebMethod 是:

[WebMethod, ScriptMethod]
public static bool Login(string userName, string password)
{
    return SecurityManager.Instance.Login(userName: userName, password: password);
}

另外,我正在使用 jquery.form.js 库(http://www.malsup.com/jquery/form/#getting-started)。如果使用单独的 $.ajax() 如下所示,它可以工作,所以我不知道在使用 jquery.form.js 时是否需要使用一些特殊的东西。

$("#frmLogin").submit(function (event) {
    //stop form from submitting normally
    event.preventDefault();

    //Get form values
    var strUsername = $("#txtUsername").val(),
    strPassword = $("#txtPassword").val();

    //Call the login function
    $.ajax({
        type: "POST",
        url: "Default.aspx/Login",
        data: "{userName: '" + strUsername + "', password: '" + strPassword + "'}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data, textStatus, jqXHR) {
            if (data.d) {
                alert("OK");
            }
            else {
                alert("NO");
            }
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert(errorThrown);
        },
    });
});

编辑 1: 我得到的完整错误消息是:

{“消息”:“无效的 JSON 原语:%7B\u00261=%22\u00262=u\u00263=s\u00264=e\u00265=r\u00266=N\u00267=a\u00268=m\u00269=e\ u002610=%22\u002611=%3A\u002612=%22\u002613=a\u002614=b\u002615=c\u002616=%22\u002617=%2C\u002618=%22\u002619=p\u002620=a\ u002621=s\u002622=s\u002623=w\u002624=o\u002625=r\u002626=d\u002627=%22\u002628=%3A\u002629=%22\u002630=1\u002631=2\u002632=3 \u002633=%22\u002634=%7D.","StackTrace":" 在 System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(字符串输入,Int32 depthLimit,JavaScriptSerializer 序列化程序)\r\n 在 System.Web.Script .Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer 序列化程序,字符串输入,类型类型,Int32 depthLimit)\r\n 在 System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](字符串输入)\r\n 在 System.Web 。脚本。Services.RestHandler.GetRawParamsFromPostRequest(HttpContext context, JavaScriptSerializer 序列化程序)\r\n 在 System.Web.Script.Services.RestHandler.GetRawParams(WebServiceMethodData methodData, HttpContext context)\r\n 在 System.Web.Script.Services.RestHandler。 ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.ArgumentException"}

编辑 2: 使用 Firebug 我已经看到我传递的 JSON 数据是 URLEnconded。这是 Firebug 在请求中显示的内容:

0=%7B&1=%22&2=u&3=s&4=e&5=r&6=N&7=a&8=m&9=e&10=%22&11=%3A&12=%22&13=a&14=b&15=c&‌​16=%22&17=%2C&18=%22&19= p&20=a&21=s&22=s&23=w&24=o&25=r&26=d&27=%22&28=%3A&29=%22‌​&30=1&31=2&32=3&33=%22&34=%7D

编辑 3: 我正在审查更多内容,看来错误出在表单插件上。如果我将数据设置为:

data: { userName: 'abc', password: '123' },

萤火虫显示:“userName=abc&password=123”。所以似乎即使我将类型参数设置为 POST,参数也会转换为查询字符串。如果我这样做:

data: $.toJSON({ userName: 'abc', password: '123' }),

然后数据得到 URLEncoded。如何使表单插件将数据作为 JSON 对象发送?

编辑 4: 我一直在调试 jquery.form.js 库,发现它总是 URLEnconding 数据,假设它总是作为查询字符串发送。在从 115 到 120 的行中,有这样的:

var elements = [];
var qx, a = this.formToArray(options.semantic, elements);
if (options.data) {
    options.extraData = options.data;
    qx = $.param(options.data, traditional);
}

qx 的结果值为: "0=%7B&1=%22&2=u&3=s&4=e&5=r&6=N&7=a&8=m&9=e&10=%22&11=%3A&12=%22&13=v&14=a&15=l&16=u&17=e&18 =1&19=%22&20=%2C&21=%22&22=p&23=a&24=s&25=s&26=w&27=o&28=r&29=d&30=%22&31=%3A&32=%22&33=v&34=a&35=l&36=u&37=e&38=2&39=% 22&40=%7D"。然后,在从 135 到 145 的行中,qx 转换为 q,并将 q 分配给 options.data(替换我作为参数发送的 JSON 对象):

var q = $.param(a, traditional);
if (qx) {
    q = (q ? (q + '&' + qx) : qx);
}
if (options.type.toUpperCase() == 'GET') {
    options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
    options.data = null;  // data is null for 'get'
}
else {
    options.data = q; // data is the query string for 'post'
}

如果我不让库替换它在 options.data 中的内容,那么一切正常。有任何想法吗?我应该解决这个问题还是应该使用不同的方法来实现我想要的?

编辑 5: 在 jquery-1.8.3.js 库中,从 7870 到 7872 的行我发现了这个:

if ( s.data && s.processData && typeof s.data !== "string" ) {
    s.data = jQuery.param( s.data, s.traditional );
}

这是在ajax(方法)内部。如您所见,该库仅在条件为真时才对数据进行编码(通过 jQuery.param() 方法)。否则,它来了就走了。但是,jquery.form.js 库总是调用 jQuery.param() 方法,如下所示(并在我的编辑 4中指出):

if (options.data) {
    options.extraData = options.data;
    qx = $.param(options.data, traditional);
}

有什么想法吗?有谁知道如何联系 jquery 表单插件的开发人员?我已经通过 Twitter 尝试过,但没有运气。

这是非常令人沮丧的。任何帮助表示赞赏。

谢谢。

4

3 回答 3

2

JSON 需要双引号。发送的数据不是

data: '{"userName": "abc","password":"123"}',

参考:http: //json.org/

站点看起来很原始,但站点发起者开发了 JSON 规范和解析 JSON 的现代浏览器中使用的方法

于 2013-01-02T03:35:28.397 回答
0

您应该将字段值添加到对象,如下所示,然后将该对象传递给将在所需事件上调用的函数。

//make object that will have values from form
var dataToSend = {
                    fieldname: $("FIELDCLASS OR ID").val();
                  };

  function tocall(){
       $.ajax({
                 url: urlForSaving,
                 data: JSON.stringify(dataToSend),
                 cache: false,
                 type: 'POST',
                 dataType: 'json',
                 contentType: "application/json;charset=utf-8",
                 success: function (data, status) {
             },
                 error: function (xhr, ajaxOptions, thrownError) { alert('error') }
             });
                   };

或者你也可以用serialize()方法序列化表单,google一下。

于 2013-01-02T05:27:26.957 回答
0

好的。我想我得自己回答。这不是我所期望的解决方案,但我想在我可以从其他人那里获得更多信息或者我能够联系开发人员之前,这可以帮助面临同样问题的其他人。好吧,在查看了jquery表单插件的代码后,我发现该库总是对数据进行URLEncoding,而jquery库中的ajax()方法则不是。因此,我已将 jquery 表单修复如下。我不是专家,所以我所做的可能不是最好的,但它会让我继续前进,直到我找到更好和永久的解决方案:

  1. 我已将以下代码替换为第 117 到 120 行:

    我改变了这个:

    if (options.data) {
        options.extraData = options.data;
        qx = $.param(options.data, traditional);
    }
    

    对此:

    if (options.data && options.processData && typeof options.data !== "string") {
        options.extraData = options.data;
        qx = $.param(options.data, traditional);
    }
    
  2. 如果在 136 到 138 的行中,我在下面添加了一个 else

    我改变了这个:

    if (qx) {
        q = ( q ? (q + '&' + qx) : qx );
    }
    

    对此:

    if (qx) {
        q = ( q ? (q + '&' + qx) : qx );
    }
    else {
        q = options.data;
    }
    

谢谢。

于 2013-01-02T23:25:58.023 回答