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<Marker> Markers)
{
return "Received " + Markers.Count + " markers.";
}
また、お好みでMarker[] Markers
のような配列を受け取ることもできます。 ASMX ScriptServicesが使用しているデシリアライザ(JavaScriptSerializer)はかなり柔軟で、入力データを指定したサーバー側の型に変換するためにできる限りのことをしてくれます。
1.markers
は JSON オブジェクトではありません。これは通常のJavaScriptオブジェクトです。
2.data:`オプションについて読むを参照してください。
サーバーに送信するデータです。文字列でない場合は、クエリ文字列に変換されます。
データをJSONとして送信したい場合は、最初にエンコードする必要があります。
data: {markers: JSON.stringify(markers)}
jQueryはオブジェクトや配列を自動的にJSONに変換しません。
しかし、エラーメッセージは、サービスの応答を解釈することから来ていると推測されます。送られてきたテキストはJSONではありません。JSONの文字列は二重引用符で囲む必要があります。だから、'しなければならないのです。
return "\"received markers\"";
実際に問題となっているのが、データの送信なのか受信なのかはわかりません。
私もこの問題に遭遇しましたが、これが私の解決策です。
データを解析する際に、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 ...