Jquery Ajaxによるjsonのウェブサービスへの投稿

JSONオブジェクトをasp.netのウェブサービスに投稿しようとしています。

私のjsonは次のようなものです。

var markers = { "markers": [
  { "position": "128.3657142857143", "markerPosition": "7" },
  { "position": "235.1944023323615", "markerPosition": "19" },
  { "position": "42.5978231292517", "markerPosition": "-3" }
]};

私はjson2.jsを使って、jsonオブジェクトをstringyfyしています。

そして、それをウェブサービスにポストするためにjqueryを使用しています。

  $.ajax({
        type: "POST",
        url: "/webservices/PodcastService.asmx/CreateMarkers",
        data: markers,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(data){alert(data);},
        failure: function(errMsg) {
            alert(errMsg);
        }
  });

以下のようなエラーが発生します。

"無効なJSONプリミティブです。

この問題に関連する多くの投稿を見つけ、それは本当に一般的な問題のようですが、何を試しても問題は解決しません。

firebugでサーバーに投稿されている内容を確認すると以下のようになります。

markers%5B0%5D%5Bposition%5D=128.3657142857143&markers%5B0%5D%5BmarkerPosition%5D=7&markers%5B1%5D%5Bposition%5D=235.1944023323615&markers%5B1%5D%5BmarkerPosition%5D=19&markers%5B2%5D%5Bposition%5D=42.5978231292517&markers%5B2%5D%5BmarkerPosition%5D=-3

呼び出されている私のウェブサービス関数は

[WebMethod]
public string CreateMarkers(string markerArray)
{
    return "received markers";
}
ソリューション

json2.jsを使ってデータを文字列化しているとのことですが、POSTされたデータはURLEncoded JSONのようです。 すでにご覧になっているかもしれませんが、不正なJSONプリミティブに関するこの投稿には、JSONがURLEncodedになっている理由が書かれています。

私は生の、手動でシリアライズされたJSON文字列をメソッドに渡すことには反対することをお勧めします。 ASP.NET はリクエストの POST データを自動的に JSON デシリアライズするため、手動で JSON 文字列をシリアライズして ASP.NET に送信すると、実際には JSON シリアル化された文字列を JSON シリアル化しなければならないことになります。

私は、もっとこのようなことを提案します。

var markers = [{ "position": "128.3657142857143", "markerPosition": "7" },
               { "position": "235.1944023323615", "markerPosition": "19" },
               { "position": "42.5978231292517", "markerPosition": "-3" }];

$.ajax({
    type: "POST",
    url: "/webservices/PodcastService.asmx/CreateMarkers",
    // The key needs to match your method's input parameter (case-sensitive).
    data: JSON.stringify({ Markers: markers }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data){alert(data);},
    failure: function(errMsg) {
        alert(errMsg);
    }
});

無効なJSONプリミティブの問題を回避するには、JavaScriptオブジェクトではなくJSON文字列をdataパラメータとしてjQueryに渡すことで、jQueryがデータをURLEncodeしようとしないようにすることです。

サーバーサイドでは、メソッドの入力パラメータを、渡すデータの形状に合わせます。

public class Marker
{
  public decimal position { get; set; }
  public int markerPosition { get; set; }
}

[WebMethod]
public string CreateMarkers(List Markers)
{
  return "Received " + Markers.Count + " markers.";
}

また、お好みでMarker[] Markersのような配列を受け取ることもできます。 ASMX ScriptServicesが使用しているデシリアライザ(JavaScriptSerializer)はかなり柔軟で、入力データを指定したサーバー側の型に変換するためにできる限りのことをしてくれます。

解説 (13)

1.markers は JSON オブジェクトではありません。これは通常のJavaScriptオブジェクトです。 2.data:`オプションについて読むを参照してください。

サーバーに送信するデータです。文字列でない場合は、クエリ文字列に変換されます。

データをJSONとして送信したい場合は、最初にエンコードする必要があります。

data: {markers: JSON.stringify(markers)}

jQueryはオブジェクトや配列を自動的にJSONに変換しません。


しかし、エラーメッセージは、サービスの応答を解釈することから来ていると推測されます。送られてきたテキストはJSONではありません。JSONの文字列は二重引用符で囲む必要があります。だから、'しなければならないのです。

return "\"received markers\"";

実際に問題となっているのが、データの送信なのか受信なのかはわかりません。

解説 (9)

私もこの問題に遭遇しましたが、これが私の解決策です。

データを解析する際に、Jsonの文字列が正しいとわかっているにもかかわらず、invalid json object例外が発生する場合は、ajaxコードで受け取ったデータを文字列化してからJSONに解析してください。

$.post(CONTEXT+"servlet/capture",{
        yesTransactionId : yesTransactionId, 
        productOfferId : productOfferId
        },
        function(data){
            try{
                var trimData = $.trim(JSON.stringify(data));
                var obj      = $.parseJSON(trimData);
                if(obj.success == 'true'){ 
                    //some codes ...
解説 (0)