JSONP和ASMX Web服务
我正在试图弄清楚如何使用jQuery对ASMX Web服务进行JSONP调用。 这些只是我已经阅读过的一些页面,但没有找到任何解决方案:
如何使用jquery“jsonp”调用外部Web服务?
使用jQuery将跨域JSON发布到ASP.NET
使用JQuery访问ASP.net webservice时出错 – JSONP
使用jQuery.ajax和JSONP设置标头?
http://www.codeproject.com/Articles/43038/Accessing-Remote-ASP-NET-Web-Services-Using-JSONP
http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/
等等…
这是我的示例.NET Web方法:
[WebMethod] [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] public void GetEmployee(string employeeId, string callback) { // Get the employee object from the Factory. Employee requestedEmployee = EmployeeFactory.GetEmployee(employeeId); if(requestedEmployee != null) { // Return the padded JSON to the caller. CrossDomainUtility.SendJsonP(callback, requestedEmployee.ToJson()); } }
这是SendJsonP():
public static void SendJsonP(string callback, string json) { // Clear any response that has already been prepared. HttpContext.Current.Response.Clear(); // Set the content type to javascript, since we are technically returning Javascript code. HttpContext.Current.Response.ContentType = "application/javascript"; // Create a function call by wrapping the JSON with the callback function name. HttpContext.Current.Response.Write(String.Format("{0}({1})", callback, json)); // Complete this request, to prevent the ASMX web service from doing anything else. HttpContext.Current.ApplicationInstance.CompleteRequest(); }
这里有一些示例jquery代码:
$.ajax({ url: 'http://devserver/service/service.asmx/GetEmployee', dataType: 'jsonp', contentType: 'application/json', data: { employeeId: '123456789' } });
我有[ScriptService]装饰的Web服务,我将我的web.config配置为使用ScriptHandlerFactory处理* .asmx。
我尝试使用ASMX在Content-Type为’application / json’时使用的内置JSON序列化,但是有一些问题:它不能用于JSONP,因为填充需要包裹在.NET不支持的JSON。 它也不起作用,因为为了序列化JSON,ASMX需要一个’ContentType:application / json’标头,但jQuery在发送GET请求时忽略ContentType标头(可能是因为它没有发送任何内容)。 我已经尝试在Global.asax Application_BeginRequest()中设置Request.ContentType =“application / json”但是没有做任何事情。 我也尝试使用beforeSend()在jQuery中设置请求标头,但没有运气。
因为我无法使用内置的.NET管道轻松地工作,所以我推出了我自己的技术,它对Response主体执行原始写入(因此SendJsonP()方法)。 我仍然遇到问题,因为即使GetEmployee()Web方法没有返回值,.NET也会抛出序列化错误,因为它试图将对象序列化为XML,因为我无法传递ContentType的’应用程序/ json’与GET请求。
因此,无论我做什么都无法让jQuery添加ContentType,我想通过使用Fiddler2创建手动请求来测试我的Web服务:
GET http://devserver/service/service.asmx/GetEmployee?callback=createMember&memberId=123456789 User-Agent: Fiddler Content-Type: application/json Host: devserver
…它会出现以下错误,因为我的参数不是JSON:
{"Message":"Invalid JSON primitive: createMember [....] }
毕竟,我还有几个问题:
-
有没有办法使用内置的.NET序列化将填充应用于JSON并将其返回给客户端?
-
由于看起来我必须自己滚动,在将带参数的JSONP查询发送到ASMX页面时,我的查询字符串应如何显示? 它必须是JSON格式,但我尝试了以下内容并收到“无效的JSON原语”错误:
GetEmployee?{callback:“createMember”,memberId:“99999999”}
?getEmployee的回调= {回调: “createMember”}&MEMBERID = {MEMBERID: “123456789”}
-
有没有办法让jQuery发送带有JSONP GET请求的ContentType标头?
我刚刚决定手动处理JSONP请求。 在我的解决方案中,用户必须通过GET请求提供两个查询字符串参数,以表明他们需要JSONP结果:callback = callbackFunctionName和jsonp = true。 如果收到这两个,我将手动处理,否则请求将继续到标准ASMX处理器。
我已经创建了一个新的JsonPUtility助手类,我在HttpApplication.BeginRequest事件中添加了一个调用:
public class Global : System.Web.HttpApplication { protected void Application_BeginRequest(object sender, EventArgs e) { // Requests for JSONP requests must be handled manually due to the limitations of JSONP ASMX. JsonPUtility.ProcessJsonPRequest(); } }
这是JsonPUtility类:
/* * JSON is Javascript Object Notation, a standard way of serializing objects in Javascript and * other languages. For more information see http://www.json.org/. * * JSONP is a technique to enable the execution of Javascript that resides in a different domain. It * works by exploiting the exception granted to the
我希望这可以在将来帮助某人。
谢谢,文斯