使用jquery,jquery表单插件和ASP.Net WebMethod的无效JSON原语

时间:2013-01-02 03:25:57

标签: jquery asp.net ajax json webmethod

我遇到了通过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 =一个\ 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。 System.Web.Script.Serialization.JavaScriptSerializer.Deserialize [T](字符串输入)\ r \ n中的Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer序列化程序,字符串输入,类型类型,Int32 depthLimit)\ r \ n System.Web.Script.Script.Script.Services.RestHandler.GetRawParams(WebServiceMetho)中的System.Web.Script.Services.RestHandler.GetRawParamsFromPostRequest(HttpContext上下文,JavaScriptSerializer序列化程序)\ r \ n dData 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&amp; 6 = N及7 =一个和8 =米和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&amp; 25 =的R&amp; 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&amp; password = 123”。所以看起来即使我将type参数设置为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&amp; 1 =%22&amp; 2 = u&amp; 3 = s&amp; 4 = e&amp; 5 = r&amp; 6 = N&amp; 7 = a&amp; 8 = m&amp; 9 = E&安培; 10 =%22和11 =%3A和; 12 =%22安培; 13 = v&安培; 14 = A&安培; 15 = 1&安培; 16 = U&安培; 17 = E和18 = 1&安培; 19 =%22安培; 20 =% 2C&安培; 21 =%22安培; 22 = p&安培; 23 = A&安培; 24 = S&安培; 25 = S&安培; 26 = W&安培; 27 =的O&amp; 28 =的R&amp; 29 = d&安培; 30 =%22安培; 31 =%3A和; 32 =%22&amp; 33 = v&amp; 34 = a&amp; 35 = 1&amp; 36 = u&amp; 37 = e&amp; 38 = 2&amp; 39 =%22&amp; 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试过,但没有运气。

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

感谢。

3 个答案:

答案 0 :(得分:2)

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

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

参考:http://json.org/

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

答案 1 :(得分: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 it。

答案 2 :(得分: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;
    }
    
  3. 感谢。