【问题标题】:Is there a way to map a virtual directory for *.asmx methods in ASP.Net 2.0?有没有办法为 ASP.Net 2.0 中的 *.asmx 方法映射虚拟目录?
【发布时间】:2012-06-11 23:49:21
【问题描述】:

不久前,我设法让 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 的方法会再次破坏返回 XML 的方法。

虽然我在任何地方都找不到任何支持文档,但这种行为让我相信在 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 的方法共存于同一模块中?

【问题讨论】:

    标签: c# asp.net vb.net json asmx


    【解决方案1】:

    +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,现在框架根据调用者返回 XML JSON。

    如果调用者指定 contentTypeapplication/xml,则返回 XML。

    如果调用者指定 contentTypeapplication/json,则返回 JSON。

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

    感谢您至少查看。

    【讨论】:

      【解决方案2】:

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

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

      “正如我之前提到的,一个规定是,如果这些 ScriptServices 被正确请求,则仅返回 JSON 序列化结果。否则,即使标记有该属性的服务也会返回 XML 而不是 JSON。我只能假设这是一部分误认为 ASMX 服务无法使用 JSON 响应的原因。”

      【讨论】:

      • 我对文章和网站都很熟悉 :) 问题不在于我不能返回 JSON。问题是我显然无法让返回 JSON 的方法与返回 XML 的方法共存于同一个模块中。
      猜你喜欢
      • 2021-10-13
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      相关资源
      最近更新 更多