【问题标题】:Make a single WCF service support both SOAP, REST and WSDL使单个 WCF 服务同时支持 SOAP、REST 和 WSDL
【发布时间】:2010-12-16 10:18:41
【问题描述】:

我正在尝试在 .NET 3.5 中构建一个同时支持 SOAP(并显示 WSDL)和 REST 的 C# 服务。

使用ServiceHostBasicHttpBinding 类很容易生成SOAP 服务和WSDL。成功了,客户很高兴。

由于 SOAP 调用都使用了简单的参数,客户端开发人员为某些命令请求了一个 REST 接口。因此,我将 ServiceHost 类更改为 WebServiceHost,添加了必要的 WebInvokeWebGet 属性,添加了 WebHttpBinding 类,然后宾果游戏 - REST 和 SOAP 都在一个服务中工作。太酷了,换一个界面,REST 和 SOAP 都得到了新的东西。

但是有一个问题 - WSDL 不再生成。我无法浏览到 http://server/service?wsdl 并获取 WSDL 文件。检查 MSDN 文档,这似乎是默认 WebServiceHost 的行为。

问题:我可以覆盖此行为以便获取 WSDL 吗?不必使用与以前相同的 URL - 它可以更改 - 但我只需要为服务提供一些 URL 即可为那些 SOAP 开发人员获取 WSDL。

【问题讨论】:

  • 您好 Jason,我很想知道您是否仍在使用这种方法,以及它如何为您工作或不工作。您是否发现必须复制任何方法(核心逻辑)来支持两者?
  • 我只需要创建两个端点并为每个命令添加一个额外的属性。

标签: c# wcf rest soap wsdl


【解决方案1】:

当您说“添加了一个 WebHttpBinding 类”时,听起来您是在代码中而不是在配置文件中进行大量配置。

如果是这种情况,您可以尝试将配置移至配置文件。然后为合约创建 2 个端点,一个 REST 和一个 SOAP,具有 2 个不同的地址和绑定。

【讨论】:

  • 我在代码中进行所有配置,而不是配置文件。一种解决方案是使用两个端点 - 该解决方案确实可以正常工作。我希望使用单个端点;单个端口和根 URL。
  • 我不认为您可以从 WebHttpBinding 端点获取 WSDL。
【解决方案2】:

但是有一个问题 - WSDL 不再 生成。我无法浏览到 http://server/service?wsdl 并获取 WSDL 文件。检查 MSDN 文档, 这似乎是一个行为 默认 WebServiceHost。

是的 - 这是 REST 的缺点之一 - 不再有 WSDL,不再有机器可读的服务描述。您需要希望服务提供商为您提供有关您可以做什么的可用且最新的文档。

没有用于 REST 的 WSDL - 期间。无法打开或任何东西 - 它只是不存在。

正在努力提供类似的东西 - 称为WADL(Web 应用程序描述语言),但据我所知,它仍然远未成为既定标准。另见:Do we need WADL?

【讨论】:

  • 我可以理解 REST 没有 WSDL,但请记住,该服务同时处理 REST 和 SOAP 请求。只是 SOAP 客户端不能再请求 WSDL。目标是拥有一个单一的服务,一个单一的监听端口,可以同时为 REST、SOAP 和 WSDL 提供服务,所有这些都基于 URL 路径。
【解决方案3】:

Circa,2007,WSDL v2.0 应该能够描述 RESTful 服务。我发现使用 .Net v4.0 中的 WCF,从纯 RESTful 服务生成的 WDSL 无效(WSDL v1.0?)。

我创建了一个类似的项目,它同时公开了 SOAP 和 RESTful 端点,并通过像您所做的那样修改接口来启用它:

    // Get all Categories - complex object response
    [OperationContract]                             // categories
    [WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetAllCategories")]
    CategoryCollection GetAllCategories();          // SubSonic object
    [OperationContract]                             // categories - respond with a JSON object
    [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetAllCategories.JSON")]
    CategoryCollection GetAllCategoriesJSON();      // SubSonic object

对此的一个警告是,对于所有 SOAP 请求,所有输入参数现在都必须是字符串类型。

有什么办法解决这个问题?

【讨论】:

  • 有没有办法在 SOAP 和 REST 中公开完全相同的方法,而不是为每个旧的 soap 方法添加一个新方法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 2013-01-24
  • 2011-11-06
  • 2021-05-14
  • 2020-12-15
相关资源
最近更新 更多