0

不久前,我设法让 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.”,这是意外的,因为返回类型都定义为XmlDocument)。

如果我简单地注释掉返回 JSON 的方法,返回 XML 的方法会正常运行。取消注释 JSON-returning 方法会再次破坏 XML-returning 方法。

虽然我在任何地方都找不到任何支持文档,但这种行为让我相信在 ASP.Net 2.0 中,返回 JSON 的方法不能与返回 XML 的方法共存于同一模块中。

这导致我尝试将子类中的方法分开,如下所示:

<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
  • ~/MyWebServices.asmx/json.MethodName

不幸的是,这不起作用,给出了 404-Not Found 错误。

我可以简单地将所有返回 JSON 的方法放入不同的 ASMX 中,但我希望有更好的方法。

我的问题是:

  • 有没有办法完成~/MyWebServices.asmx/xml/MethodName~/MyWebServices.asmx/json.MethodName?我喜欢在虚拟路径中按返回类型分隔函数的想法。
  • 如果做不到这一点,有没有办法让返回 JSON 的方法与返回 XML 的方法共存于同一个模块中?
4

2 回答 2

1

我惊讶地发现您对这个限制是正确的,但是它仅适用于 .asmx 脚本服务。通常,您仍然可以使用 ASP.NET 2.0+ 返回所需的任何类型(和组合)的内容类型。

我发现这篇文章解释了这些限制并澄清了对 ASMX/JSON 的误解: http://encosia.com/asmx-and-json-common-mistakes-and-misconceptions/。相关摘录说:

“正如我之前提到的,一个规定是,如果请求正确,这些 ScriptServices 只会返回 JSON 序列化结果。否则,即使是标记有该属性的服务也会返回 XML 而不是 JSON。我只能假设这是部分原因对于 ASMX 服务无法使用 JSON 响应的误解。”
于 2012-06-07T21:24:11.943 回答
0

向@smartcaveman +1 尝试。

对此的解决方案是一种不同的(我认为总体而言更好)的方法。我没有显式返回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,现在框架根据调用者返回 XML或JSON。

如果调用者指定 a contentTypeof application/xml,则返回 XML。

如果调用者指定 a contentTypeof application/json,则返回 JSON。

我认为这种方法更好,因为我不必按返回类型组织 WebServices,也不必为我编写的每个 WebService 维护两个单独的方法(一个 XML,一个 JSON)。

谢谢你至少看。

于 2012-06-11T16:38:52.070 回答