【问题标题】:Hide REST endpoint from MEX/WSDL in WCF从 WCF 中的 MEX/WSDL 隐藏 REST 端点
【发布时间】:2010-03-02 01:12:46
【问题描述】:

我有一个 WCF 服务,每个服务都有 REST 和 SOAP 端点。这与这篇文章的实现类似:REST / SOAP endpoints for a WCF service,配置类似于以下:

<services>
  <service name="TestService">
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
    <endpoint address="rest" binding="webHttpBinding" contract="ITestService"/>
  </service>
</services>

问题在于 REST 端点在生成的 WSDL 中显示为附加端口和绑定。

有什么方法可以防止 REST 端点被包含在 WSDL 中?

【问题讨论】:

    标签: wcf rest soap wsdl


    【解决方案1】:

    您可以获取 WSDL 的副本,手动对其进行编辑以删除不需要的工件,并将其存储在已知位置。一旦您拥有删除不需要的工件的 WSDL 版本,您就可以将 ?wsdl 查询重定向到该位置:

    <behaviors>
     <serviceBehaviors>
        <behavior name="TestServiceBehavior">
         <serviceMetadata httpGetEnabled="True" externalMetadataLocation="http://localhost/TestService.wsdl"/>
        </behavior>
     </serviceBehaviors>
    </behaviors>
    

    关于此解决方案的一些注意事项。您必须小心编辑的内容。如果您更改合同的关键方面,WCF 可能无法处理从它生成的客户端的消息。删除端点通常没什么大不了的,但是更改绑定、操作、消息类型等的名称可能会导致问题。

    您还需要注意导入。 WCF 生成的 WSDL 通常定义端点,然后导入另一个定义实际服务契约的 .wsdl。 tern 中的服务契约 wsdl 通常会导入几个定义消息和数据类型的 .xsd 文件。您需要确保已上传这些相对于根 .wsdl 的副本,并更新导入元素以适当地引用它们。

    另一个问题是您现在手动控制您的合同...这意味着如果您更改它,您必须再次编辑它并在您托管 .wsdl 文件的任何站点上替换它。现在,一个设计合理的合同永远不会改变,因为这违反了关于 Web 服务的基本 SOA 规则之一。但是,您似乎在进行代码优先开发,因此需要注意。

    【讨论】:

    • 手动解决方案将起作用,但是正如您所指出的,它远非理想。无论好坏,这项服务将随着时间的推移而不断发展,并定期添加新方法,因此合同将发生变化。我正在寻找一种更加自动化的解决方案,因此我不必记得在每次服务增强时都使用 WSDL。
    • 没有理由不能自动化这个过程。它都是 XML,编写一些过程应该很容易,甚至可能是一个 powershell 脚本,作为部署过程的一部分运行。它可以从正常的 ?wsdl 查询中提取所有文件,使用 XPath 查找并删除所需的元素,并部署所有 .wsdl 和 .xsd 文件。最后,它可以自动更新配置以将 元素添加到您的绑定行为中。
    【解决方案2】:

    如果有一个属性来装饰端点,以便在 WCF 的未来版本中对 mex/wsdl 生成隐藏,正是出于这个原因(对肥皂客户端隐藏 restful 服务),那就太好了。

    【讨论】:

      【解决方案3】:

      使用IWsdlExportExtension 找到了一种体面的方法。可能有一种更健壮/可重用的方法来执行此操作,但此解决方案需要将所有 REST 端点的约定命名为“REST”。以下是附加到所有 REST 端点的端点行为的相关部分:

      public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
      {
          // Remove all REST references (binding & port) from SOAP WSDL
          foreach (ServiceDescription wsdl in exporter.GeneratedWsdlDocuments)
          {
              // Remove REST bindings
              foreach (Binding binding in wsdl.Bindings)
              {
                  if (binding.Name == "REST")
                  {
                      wsdl.Bindings.Remove(binding);
                      break;
                  }
              }
      
              // Remove REST ports
              foreach (Service service in wsdl.Services)
              {
                  foreach (Port port in service.Ports)
                  {
                      if (port.Name == "REST")
                      {
                          service.Ports.Remove(port);
                          break;
                      }
                  }
              }
          }  
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-04
        • 1970-01-01
        • 1970-01-01
        • 2018-05-14
        • 2020-11-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多