使用来自.NET服务的jQuery获取JSON数据:与ajax设置混淆

我刚刚花了六个小时试图把这个直接放在我脑海里,但我还没有成功。

我的本地机器上有一个HelloWorld .NET 3.5 Web服务。 根据需要进行设置 。
该服务返回自定义结构List

我正在尝试使用jQuery 1.4.4来使用它。

当我尝试执行文档所说的内容时,我总是从服务中获取XML响应,这会导致jQuery中的parseerror或者作为哑字符串传递给success函数。 也就是说,我结合了dataTypeaccepts (根据文档控制接收数据的处理方式),我得到了一个XML。

但是,当我从文档中做一些逻辑上不合适的事情时,我成功地获取了我的对象数组。 也就是说,当我忽略dataTypeaccepts ,并设置contentType: "application/json; charset=utf-8" ,它工作正常。 但是,根据文档, contentType控制发送到服务器的数据,而不是接收到的数据。


在代码中:

 $.ajax( { type: "GET", url: "http://localhost:52624/Service1.asmx/HelloWorld", dataType: "json", //accepts can be anything, or it can be missing, doesn't matter, only depends on dataType success: function(data, textStatus, jqXHR) {...}, error: function(jqXHR, textStatus, errorThrown) {...} } ) 

结果:调用error handling程序,textStatus = parseerror


 $.ajax( { type: "GET", url: "http://localhost:52624/Service1.asmx/HelloWorld", dataType: "application/json", //accepts can be anything, or it can be missing, doesn't matter, only depends on dataType success: function(data, textStatus, jqXHR) {...}, error: function(jqXHR, textStatus, errorThrown) {...} } ) 

结果:Web服务返回XML,它以string传递给成功处理程序。


 $.ajax( { type: "GET", url: "http://localhost:52624/Service1.asmx/HelloWorld", accepts: "json", // or "application/json" success: function(data, textStatus, jqXHR) {...}, error: function(jqXHR, textStatus, errorThrown) {...} } ) 

结果:Web服务返回XML,它被解析并作为IXMLDOMDocument2传递。


 $.ajax( { type: "GET", url: "http://localhost:52624/Service1.asmx/HelloWorld", contentType: "application/json; charset=utf-8", success: function(data, textStatus, jqXHR) {...}, error: function(jqXHR, textStatus, errorThrown) {...} } ) 

结果:Web服务返回JSON,它被jQuery部分解析(数字和字符串被解析为对象的属性,但是日期保持为"/Date(1303003305724)/" )。


问题:

  1. 我完全理解jQuery规范吗? 为什么据说控制发送数据的参数实际上控制了接收数据?
  2. 我在做什么明显错误?
  3. 获取由jQuery解析日期的最后一步是什么?

看起来我自己会回答这个问题。
我不是说以下是绝对的事实。 相反,这是我发现的工作。


首先,我发现了三篇解释很多的文章:

  • 使用jQuery来使用ASP.NET JSON Web服务
  • ASMX ScriptService错误 – 无效的JSON原语
  • 在ASP.NET AJAX中使用jQuery时要避免3个错误

简而言之,.NET Web服务的问题在于您必须以特殊方式调用它们:

  • 使用POST请求(但见下文)
  • 提供Content-Type of application/json; charset=utf-8 application/json; charset=utf-8

这是出于设计和出于安全原因。
后者可能无法避免,您必须提供该内容类型。 并且因为内容类型确定了请求中参数的编码方式,所以必须使用JSON对参数进行编码。

这就是jQuery跳入的地方。无论如何,jQuery会忽略contentType并在application/x-www-form-urlencoded编码你的参数。 此时,Web服务将不喜欢您说“这里是JSON”并提供表单编码的东西。

在这些文章中,作者建议您通过将JSON数据包含在另一对引号中来使用jQuery来玩耍,这样它就会被解释为字符串并且不会被jQuery搞砸:

 $.ajax({ type: "POST", url: "ServiceName.asmx/WebMethodName", data: "{'fname':'dave','lname':'ward'}", contentType: "application/json; charset=utf-8", dataType: "json", success: function(msg) {...} }); 

这确实有效。

此外,如果您没有任何数据,您仍然必须提供一个空的JSON对象{} ,因为如果不这样做,jQuery将不会设置Content-Length ,如果没有Content-Length ,Web服务将再次不喜欢您(更安全的原因)。


然而。
从FW 3.5开始,可以将GET与支持JSON的.NET服务一起使用。 此时您可能想知道JSON编码的参数如何与GET请求保持一致。 这是如何做。

如果您的Web服务没有任何参数,则调用很简单:

 $.ajax( { type: "GET", url: "ServiceName.asmx/WebMethodName", contentType: "application/json; charset=utf-8", dataType: "json", success: function(data, textStatus, jqXHR) {...} } ); 

如果有参数,那么调用也很简单。 你要做的是提供应该有它们的参数的附加引号! 这是因为您希望这些引号显示为表单编码请求的一部分。 这种forms编码的请求看起来有点像json编码的:

 $.ajax( { type: "GET", url: "ServiceName.asmx/WebMethodName", contentType: "application/json; charset=utf-8", data: {DatePlaced:'"2011-05-13"'}, dataType: "json", success: function(data, textStatus, jqXHR) {...} } ); 

此请求将产生类似于以下内容的请求:

GET /ServiceName.asmx/WebMethodName?DatePlaced=”2011-05-13“HTTP / 1.1
Content-Type:application / json; 字符集= utf-8的

请注意类似JSON的GET请求所需的引号,但如果您要求使用XML,则会导致错误。

当发布到asp.net Web服务时,你总是必须将内容类型设置为 – 这是他们阻止json劫持的方式。

关于日期最简单的解决方案是返回日期作为字符串处理日期类型在客户端将是一个巨大的PITA(至少从我的经验)。

我想你不明白jQuery的规格:( 规格 )

数据类型

默认值:智能猜测(xml,json,脚本或html)

您期望从服务器返回的数据类型。 如果没有指定,jQuery将尝试根据响应的MIME类型推断它…

现在。 看看你的各种情况。

案例1:dataType:“json”。

你收到“xml”,但声明“json”=>你得到一个parseerror因为你不能解析xml就好像它是json一样。

案例2:dataType:“application / json”。

“application / json”不是有效的数据类型,因此jQuery默认为string。

案例3:没有dataType。

jQuery做出了最好的猜测,在你的情况下结果很好。

案例4:contentType:“application / json; charset = utf-8”

您要求提供json数据,而不指定dataType。 在这种情况下,您很幸运Webservice确实返回了json数据,并且jQuery正确猜测数据是json格式的。

关于日期格式化,你想看看:

如何格式化Microsoft JSON日期?