1

ASPX ページの WebMethod に jquery 経由で JSON データを送信する際に問題が発生しています。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 serializer, String input, Type type, Int32 depthLimit)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)\r\n at System.Web 。脚本。Services.RestHandler.GetRawParamsFromPostRequest(HttpContext コンテキスト、JavaScriptSerializer シリアライザー) \r\n System.Web.Script.Services.RestHandler.GetRawParams(WebServiceMethodData methodData、HttpContext コンテキスト) で\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」。そのため、type パラメータを POST に設定しているにもかかわらず、パラメータがクエリ文字列に変換されているようです。そして、私がこれを行うと:

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

その後、データは URL エンコードされます。データを 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 の結果の値は次のとおりです。 =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(メソッド)の中にあります。ご覧のとおり、ライブラリは、条件が true の場合にのみ (jQuery.param() メソッドを介して) データをエンコードします。それ以外の場合は、元のままになります。ただし、 jquery.form.js ライブラリは常に jQuery.param() メソッドを呼び出します。これは、以下に示すように (および私のEdit 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()または、メソッドを使用してフォームをシリアル化することもできます。

于 2013-01-02T05:27:26.957 に答える
0

Ok。自分で答えるしかないと思います。これはまさに私が期待していた解決策ではありませんが、他の人からさらに情報を得るか、開発者に連絡できるようになるまで、これは同じ問題に直面している他の人を助けることができると思います. さて、jquery フォーム プラグインのコードを確認したところ、jquery ライブラリの ajax() メソッドはそうではありませんが、ライブラリは常にデータを URL エンコードすることがわかりました。そこで、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 行の if に 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 に答える