使用 jQuery 从 .NET 服务获取 JSON 数据:与 ajax 设置混淆
Posted
技术标签:
【中文标题】使用 jQuery 从 .NET 服务获取 JSON 数据:与 ajax 设置混淆【英文标题】:Get JSON data with jQuery from a .NET service: confused with ajax setup 【发布时间】:2011-08-07 03:31:46 【问题描述】:我花了六个小时试图弄清楚这一点,但我没有成功。
我的本地计算机上有一个 HelloWorld .NET 3.5 Web 服务。 Set up as required.
该服务返回自定义结构的List
。
我正在尝试使用 jQuery 1.4.4 来使用它。
当我尝试执行the documentation 所说的操作时,我总是从服务返回一个 XML 响应,这会导致 jQuery 中的 parseerror
或作为哑字符串传递给 success
函数。 也就是说,但是我结合了 dataType
和 accepts
(根据文档,控制如何处理接收到的数据),我得到了一个 XML。
但是,当我做一些不符合文档逻辑的事情时,我成功地获得了我的对象数组。 也就是说,当我忽略 dataType
和 accepts
并设置 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) ...
)
结果:调用错误处理程序,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)/"
的形式)。
问题:
-
我了解 jQuery 规范吗?为什么说控制发送数据的参数实际上控制接收数据?
我做错了什么?
获取由 jQuery 解析的日期的最后一步是什么?
【问题讨论】:
Asmx web service how to return JSON and not XML?的可能重复 @StephenKennedy 这个问题在两年后出现,可以说包含的材料要少得多。如果有的话,您应该投票关闭 it 作为重复项。 我认为较新的版本更直接,对普通读者更有用,但我接受这是一个判断电话,其他人可能不同意:) 我撤回了我的投票,因为这个更关注 jQuery 而我今天正在看 javascriptSerializer 的东西。 【参考方案1】:看来我要自己回答了。我并不是说以下是绝对真理。相反,这是我发现的工作。
首先找到三篇解释很多的文章:
Using jQuery to Consume ASP.NET JSON Web Services ASMX ScriptService mistake – Invalid JSON primitive 3 mistakes to avoid when using jQuery with ASP.NET AJAX简而言之,.NET Web 服务的问题在于您必须以特殊方式调用它们:
使用 POST 请求(但见下文),以及 提供Content-Type
的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 请求保持一致。方法如下。
如果你的网络服务没有任何参数,调用很简单:
$.ajax(
type: "GET",
url: "ServiceName.asmx/WebMethodName",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data, textStatus, jqXHR) ...
);
而且如果有参数,那么调用也很简单。你需要做的是在应该有它们的参数周围提供额外的引号!这是因为您希望这些引号作为表单编码请求的一部分出现。这样,表单编码的请求看起来有点像 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 内容类型:应用程序/json;字符集=utf-8
注意类似 JSON 的 GET 请求所需的引号,但如果您要请求 XML,则会导致错误。
【讨论】:
【参考方案2】:当发布到 asp.net 网络服务时,您总是必须将内容类型设置为 - 这是他们防止 json 劫持的方式。
关于日期,最简单的解决方案是将日期作为字符串返回,在客户端处理日期类型将是一个巨大的 PITA(至少根据我的经验)。
【讨论】:
【参考方案3】:我认为你不了解 jQuery 规范:(Specs)
数据类型
默认:智能 猜测(xml、json、脚本或 html)
您期望的数据类型 从服务器返回。如果没有 指定,jQuery 将尝试推断它 基于响应的 MIME 类型...
现在。看看你的各种情况。
案例 1:数据类型:“json”。
你收到“xml”但声明“json”=>你得到一个解析错误,因为你不能像 json 一样解析 xml。
案例 2:数据类型:“application/json”。
"application/json" 不是有效的数据类型,所以 jQuery 默认为字符串。
案例 3:无数据类型。
jQuery 做出了最好的猜测,在你的情况下结果很好。
案例 4:contentType: "application/json; charset=utf-8"
您要求 json 数据,但您没有指定数据类型。在这种情况下,您很幸运 Web 服务确实返回了 json 数据,并且 jQuery 正确猜测数据是 json 格式。
关于日期格式,你想看看:
How do I format a Microsoft JSON date?
【讨论】:
是的,我意识到这一点。我确实认为dataType
是从服务器请求特定的数据格式,而我现在意识到它只是告诉jQuery 会得到什么结果。让我感到困惑的是,为什么指示 Web 服务返回 json(而不是 xml)的唯一方法是设置 contentType
,根据文档,这是为了不同的目的?
@Greg:这将取决于 web 服务,而不是 jQuery。 contentType 并非用于此目的,但它是发送到 Web 服务的消息的一部分。 webservice 接收它并决定做任何它想做的事情,不管它在 jQuery 中的预期目的。
那是 GSerg,不是 Greg,所以我没有收到通知 :) 好吧,让我继续。使用 .NET Web 服务时,如果您在参数中提供 json 数据,则只能获取 json 数据(因为这首先是 contentType
的用途——它的 json-summoning 副作用不会取消它所描述的事实发送到服务器的参数格式)。所以我没有application/x-www-form-urlencoded
了。但是 jQuery 会以某种方式处理这个问题。正确的?而且,鉴于这种情况,我可以使用 GET 吗?我认为 json 编码的参数需要 POST。以上是关于使用 jQuery 从 .NET 服务获取 JSON 数据:与 ajax 设置混淆的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jQuery 和 ASP.NET MVC 从 AJAX 调用返回错误消息?
如何使用jQuery调用带有参数的asp.net asmx web服务来获取响应
如何使用 jQuery 调用 ASP.NET Web 服务?