I've written a webservice which returns JSON and I've tried to call it using jQuery like this:
我写了一个返回JSON的web服务,我试着用jQuery这样调用它:
$.ajax({
contentType: "application/json; charset=utf-8",
url: "http://examplewebsite.com/service.asmx/GetData",
data: { projectID: 1 },
dataType: "jsonp",
success: function () {alert("success");}
});
However the code never calls the success function, despite the webservice call being successful when looking at the HTTP traffic using Fiddler. I think this is because my web service is returning raw JSON instead of JSONP.
然而,代码从不调用success函数,尽管使用Fiddler查看HTTP流量时webservice调用是成功的。我认为这是因为我的web服务返回的是原始JSON而不是JSONP。
How can I produce JSONP as the response from a standard .NET webservice method like this:
如何生成JSONP作为标准。net webservice方法的响应,比如:
[WebMethod(), ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public Project GetData(int projectID)
{
Project p = new Project();
p.Name = "foobar";
return p;
}
Thanks.
谢谢。
3 个解决方案
#1
43
OK, I've eventually figured it out myself. As I found it so hard to find a complete working solution on the web, I've decided to document my working solution here.
好吧,我自己也算出来了。当我发现在web上很难找到一个完整的工作解决方案时,我决定在这里记录我的工作解决方案。
A JSONP response is just standard JSON string wrapped in a function call. ASP.NET doesn't seem to provide any way to return the reponse in this format directly, but it's very simple to do this yourself. You do though, have to override the default method of JSON encoding.
JSONP响应只是包装在函数调用中的标准JSON字符串。ASP。NET似乎没有提供任何直接以这种格式返回响应的方法,但是您自己做这个非常简单。但是,您必须重写JSON编码的默认方法。
Below is an example of JSONP.
下面是JSONP的一个例子。
functionName({ name: 'value';});
functionName({名称:“价值”;});
..now this bit: { name: 'value';}
is just standard JSON that any JSON serializer will give you, so all we need to do is tack on the function call wrapper. Unfortunately, doing that means we have to 'unwire' (or bypass) the existing JSON encoding which is handled transparently by the framework when you return an object from the web service function.
. .现在这个位:{name: 'value';}是任何JSON序列化器将给您的标准JSON,所以我们需要做的就是在函数调用包装器上添加。不幸的是,这样做意味着我们必须“断开”(或绕过)现有的JSON编码,当您从web服务函数返回一个对象时,该编码将透明地处理。
This is done by overriding the response from the web service function completely by writing the JSONP to the output stream (Response) using our own code. This is actually quite straightforward and I've included an example below.
通过使用我们自己的代码将JSONP写入输出流(响应),完全覆盖来自web服务函数的响应,就可以做到这一点。这实际上非常简单,我在下面包含了一个示例。
You can use either the built in DataContractJsonSerializer (from the System.Runtime.Serialization.Json namespace in ASP.NET 3.5+) or the NewtonSoft JSON serializer, and both examples are shown below. I prefer to use the the NewtonSoft JSON (installed from nuget) rather than the built in JSON serializer as I find it gives you more control and also can output nicely formatted human readable JSON for debugging. It's also much faster on paper!
您可以使用内置的DataContractJsonSerializer(来自System.Runtime.Serialization)。Json在ASP名称空间。NET 3.5+)或NewtonSoft JSON序列化器,两个示例如下所示。我更喜欢使用NewtonSoft JSON(安装自nuget),而不是内置的JSON序列化器,因为我发现它为您提供了更多的控制,并且可以输出格式化良好的人工可读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();
}
This method can then be called using the following JQuery code:
然后可以使用以下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
}
#2
3
Thanks Nick, that was an excellent answer to a problem that I too had a hard time finding at first online. Worked great for me as well.
谢谢尼克,这是一个很好的答案,我也很难在网上找到这个问题。对我来说也很有用。
Wanted to make sure this this line of post got the attention it deserves.
想要确保这条帖子得到了应有的关注。
Just wanted to add that I used the built in serializer (System.Runtime.Serialization.Json) and it worked like a charm as well.
我只是想补充一点,我使用了内置的序列化器(system . runtime. serializ.json),而且它的工作方式也很迷人。
List<orderHistory> orderHistory = null;
StringBuilder sb = new StringBuilder();
JavaScriptSerializer js = new JavaScriptSerializer();
sb.Append(callback + "(");
sb.Append(js.Serialize(orderHistory));
sb.Append(");");
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.Write(sb.ToString());
Context.Response.End();
#3
0
In case someone is looking for sample how to return JSONP
from ASP.NET
Web API
action:
如果有人正在寻找示例,如何从ASP返回JSONP。NET Web API的行动:
// GET api/values
public JsonpResult Get()
{
var values = new string[] { "value1", "value2" };
return new JsonpResult(values);
}
JsonpResult
helper class encapsulating the JSONP
wrapping.
JsonpResult帮助类封装了JSONP包装。
public class JsonpResult : JsonResult
{
object _data = null;
public JsonpResult(object Data)
{
_data = Data;
}
public override void ExecuteResult(ControllerContext controllerContext)
{
if (controllerContext != null)
{
var Response = controllerContext.HttpContext.Response;
var Request = controllerContext.HttpContext.Request;
var callBackFunction = Request["callback"];
if (string.IsNullOrEmpty(callBackFunction))
{
throw new Exception("Callback function name must be provided in the request!");
}
Response.ContentType = "application/x-javascript";
if (_data != null)
{
var serializer = new JavaScriptSerializer();
Response.Write(string.Format("{0}({1});", callBackFunction, serializer.Serialize(Data)));
}
}
}
}
#1
43
OK, I've eventually figured it out myself. As I found it so hard to find a complete working solution on the web, I've decided to document my working solution here.
好吧,我自己也算出来了。当我发现在web上很难找到一个完整的工作解决方案时,我决定在这里记录我的工作解决方案。
A JSONP response is just standard JSON string wrapped in a function call. ASP.NET doesn't seem to provide any way to return the reponse in this format directly, but it's very simple to do this yourself. You do though, have to override the default method of JSON encoding.
JSONP响应只是包装在函数调用中的标准JSON字符串。ASP。NET似乎没有提供任何直接以这种格式返回响应的方法,但是您自己做这个非常简单。但是,您必须重写JSON编码的默认方法。
Below is an example of JSONP.
下面是JSONP的一个例子。
functionName({ name: 'value';});
functionName({名称:“价值”;});
..now this bit: { name: 'value';}
is just standard JSON that any JSON serializer will give you, so all we need to do is tack on the function call wrapper. Unfortunately, doing that means we have to 'unwire' (or bypass) the existing JSON encoding which is handled transparently by the framework when you return an object from the web service function.
. .现在这个位:{name: 'value';}是任何JSON序列化器将给您的标准JSON,所以我们需要做的就是在函数调用包装器上添加。不幸的是,这样做意味着我们必须“断开”(或绕过)现有的JSON编码,当您从web服务函数返回一个对象时,该编码将透明地处理。
This is done by overriding the response from the web service function completely by writing the JSONP to the output stream (Response) using our own code. This is actually quite straightforward and I've included an example below.
通过使用我们自己的代码将JSONP写入输出流(响应),完全覆盖来自web服务函数的响应,就可以做到这一点。这实际上非常简单,我在下面包含了一个示例。
You can use either the built in DataContractJsonSerializer (from the System.Runtime.Serialization.Json namespace in ASP.NET 3.5+) or the NewtonSoft JSON serializer, and both examples are shown below. I prefer to use the the NewtonSoft JSON (installed from nuget) rather than the built in JSON serializer as I find it gives you more control and also can output nicely formatted human readable JSON for debugging. It's also much faster on paper!
您可以使用内置的DataContractJsonSerializer(来自System.Runtime.Serialization)。Json在ASP名称空间。NET 3.5+)或NewtonSoft JSON序列化器,两个示例如下所示。我更喜欢使用NewtonSoft JSON(安装自nuget),而不是内置的JSON序列化器,因为我发现它为您提供了更多的控制,并且可以输出格式化良好的人工可读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();
}
This method can then be called using the following JQuery code:
然后可以使用以下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
}
#2
3
Thanks Nick, that was an excellent answer to a problem that I too had a hard time finding at first online. Worked great for me as well.
谢谢尼克,这是一个很好的答案,我也很难在网上找到这个问题。对我来说也很有用。
Wanted to make sure this this line of post got the attention it deserves.
想要确保这条帖子得到了应有的关注。
Just wanted to add that I used the built in serializer (System.Runtime.Serialization.Json) and it worked like a charm as well.
我只是想补充一点,我使用了内置的序列化器(system . runtime. serializ.json),而且它的工作方式也很迷人。
List<orderHistory> orderHistory = null;
StringBuilder sb = new StringBuilder();
JavaScriptSerializer js = new JavaScriptSerializer();
sb.Append(callback + "(");
sb.Append(js.Serialize(orderHistory));
sb.Append(");");
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.Write(sb.ToString());
Context.Response.End();
#3
0
In case someone is looking for sample how to return JSONP
from ASP.NET
Web API
action:
如果有人正在寻找示例,如何从ASP返回JSONP。NET Web API的行动:
// GET api/values
public JsonpResult Get()
{
var values = new string[] { "value1", "value2" };
return new JsonpResult(values);
}
JsonpResult
helper class encapsulating the JSONP
wrapping.
JsonpResult帮助类封装了JSONP包装。
public class JsonpResult : JsonResult
{
object _data = null;
public JsonpResult(object Data)
{
_data = Data;
}
public override void ExecuteResult(ControllerContext controllerContext)
{
if (controllerContext != null)
{
var Response = controllerContext.HttpContext.Response;
var Request = controllerContext.HttpContext.Request;
var callBackFunction = Request["callback"];
if (string.IsNullOrEmpty(callBackFunction))
{
throw new Exception("Callback function name must be provided in the request!");
}
Response.ContentType = "application/x-javascript";
if (_data != null)
{
var serializer = new JavaScriptSerializer();
Response.Write(string.Format("{0}({1});", callBackFunction, serializer.Serialize(Data)));
}
}
}
}