不久前,我设法让WebServices从ASPX的代码隐藏中返回JSON和XML。
今天,我需要迁移现有的 ASMX WebService来返回JSON而不是XML(这很简单。)在测试新方法时,我的问题变得明显。
在ASMX的代码隐藏中,我创建了一个返回JSON而不是XML的新方法。
该方法有效,因为它返回预期的JSON,但是新例程会破坏代码隐藏中的每个XML返回方法(它们都抛出“System.NotSupportedException: The type System.Collections.Hashtable is not supported because it implements IDictionary.
”这是意外的,因为返回类型都被定义为{{ 1}})。
如果我只是注释掉JSON返回方法,则XML返回方法正常运行。取消注释JSON返回方法会再次破坏XML返回方法。
虽然我无法在任何地方找到任何支持文档,但这种行为让我相信在ASP.Net 2.0中,JSON返回方法不能与XML返回方法共存于同一模块中。
这导致我尝试分离子类中的方法,如下所示:
XmlDocument
我的想法是,我可以用以下方式之一调用服务:
<WebService(Namespace:="http://tempura.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ScriptService()> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class MyWebServices
Inherits System.Web.Services.WebService
<ScriptService()> _
Public Class xml
Inherits System.Web.Services.WebService
<WebMethod()> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Xml)> _
Public Function MethodName As XmlDocument
...
End Function
End Class
<ScriptService()> _
Public Class json
Inherits System.Web.Services.WebService
<WebMethod()> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
Public Function MethodName As Hashtable
...
End Function
End Class
End Class
~/MyWebServices.asmx/xml/MethodName
~/MyWebServices.asmx/xml.MethodName
~/MyWebServices.asmx/json/MethodName
遗憾的是,这不起作用,给出了404-Not Found错误。
我可以简单地将所有返回JSON的方法放入不同的ASMX中,但我希望有更好的方法。
我的问题是:
~/MyWebServices.asmx/json.MethodName
和~/MyWebServices.asmx/xml/MethodName
?我喜欢在虚拟路径中按返回类型分隔函数的想法。答案 0 :(得分:1)
我很惊讶地发现您对此限制是正确的,但它仅适用于.asmx脚本服务。您仍然可以使用ASP.NET 2.0+返回任何类型(和组合)的内容类型。
我发现这篇文章解释了这些限制并澄清了对ASMX / JSON的误解: http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/。相关摘录说:
“正如我前面提到的,一个规定是这些ScriptServices只有在正确请求时才返回JSON序列化结果。否则,即使是标有该属性的服务也会返回XML而不是JSON。我只能假设它是之所以误以为ASMX服务无法用JSON响应。“
答案 1 :(得分:0)
+1给@smartcaveman尝试。
对此的解决方案是一种不同的(我认为更好的整体)方法。我没有显式返回XMLDocument
(XML)或HashTable
(JSON),而是写出了一个自定义返回对象,如下所示:
<WebService(Namespace:="http://tempura.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ScriptService()> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class MyWebServices
Inherits System.Web.Services.WebService
<WebMethod()> _
<ScriptMethod()> _
Public Function MethodName As CustomReturnObject
...
End Function
End Class
我确保自定义返回对象已实现IXmlSerializable
,现在Framework根据调用者返回XML 或 JSON。
如果调用者指定contentType
application/xml
,则返回XML。
如果调用者指定contentType
application/json
,则返回JSON。
我认为这种方法更好,因为我不必按返回类型组织WebServices,也不必为我编写的每个WebService维护两个单独的方法(一个XML,一个JSON)。
至少谢谢你。