OK、私は最終的にそれを自分で理解しました。Webで完全に機能するソリューションを見つけるのは非常に難しいと感じたので、ここで自分の機能するソリューションを文書化することにしました。
JSONP応答は、関数呼び出しでラップされた単なる標準のJSON文字列です。ASP.NETは、この形式で応答を直接返す方法を提供していないようですが、これを自分で行うのは非常に簡単です。ただし、JSONエンコーディングのデフォルトの方法をオーバーライドする必要があります。
以下はJSONPの例です。
functionName({ name: 'value';});
..今このビット:
JSONシリアライザー{ name: 'value';}
が提供する標準のJSONであるため、必要なのは関数呼び出しラッパーを追加することだけです。残念ながら、これを行うと、Webサービス関数からオブジェクトを返すときにフレームワークによって透過的に処理される既存のJSONエンコーディングを「配線解除」(またはバイパス)する必要があります。
これは、独自のコードを使用してJSONPを出力ストリーム(Response)に書き込むことにより、Webサービス関数からの応答を完全にオーバーライドすることによって行われます。これは実際には非常に簡単で、以下に例を示します。
組み込みのDataContractJsonSerializer(ASP.NET 3.5以降のSystem.Runtime.Serialization.Json名前空間から)またはNewtonSoftJSONシリアライザーのいずれかを使用できます。両方の例を以下に示します。組み込みのJSONシリアライザーではなく、 NewtonSoft JSON (nugetからインストール)を使用することを好みます。これにより、より詳細な制御が可能になり、デバッグ用に適切にフォーマットされた人間が読めるJSONを出力できるようになります。紙の上でもはるかに高速です!
[WebMethod()]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public void GetData(int projectID, string callback)
{
List<Video> videos = null;
// <code here to populate list on line above>
// Method 1: use built-in serializer:
StringBuilder sb = new StringBuilder();
JavaScriptSerializer js = new JavaScriptSerializer();
sb.Append(callback + "(");
sb.Append(js.Serialize(videos));
sb.Append(");");
// Method 2: NewtonSoft JSON serializer (delete as applicable)
// StringBuilder sb = new StringBuilder();
// sb.Append(callback + "(");
// sb.Append(JsonConvert.SerializeObject(videos, Formatting.Indented)); // indentation is just for ease of reading while testing
// sb.Append(");");
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.Write(sb.ToString());
Context.Response.End();
}
このメソッドは、次のJQueryコードを使用して呼び出すことができます。
$.ajax({
crossDomain: true,
contentType: "application/json; charset=utf-8",
url: "http://examplewebsite.com/service.asmx/GetData",
data: { projectID: 1 }, // example of parameter being passed
dataType: "jsonp",
success: onDataReceived
});
function onDataReceived(data)
{
alert("Data received");
// Do your client side work here.
// 'data' is an object containing the data sent from the web service
// Put a JS breakpoint on this line to explore the data object
}