WCF 如何确定 webHttpBinding 中使用 ASP.NET 路由的终结点地址?

How does WCF Decide the Endpoint Addresses used in webHttpBinding with ASP.NET Routing?

提问人:John Saunders 提问时间:10/9/2012 最后编辑:John Saunders 更新时间:10/11/2012 访问量:968

问:

我有一个 WCF 服务,供我们 Web 应用程序中的某些 Silverlight 代码使用。它使用 ASP.NET 路由功能:

private void RegisterRoutes()
{
    var factory = new WebServiceHostFactory();
    RouteTable.Routes.Add(new ServiceRoute("Service", factory, typeof(ServiceService)));
}

这目前适用于我们的生产环境。

在其他一些环境中,我遇到异常

System.InvalidOperationException:找不到 匹配绑定了 WebHttpBinding 的终结点的方案 http。 已注册的基址方案为 [https]。

我刚刚将完全相同的代码部署到我们的集成环境和培训环境中。它在集成中有效,但在训练中失败。这两个环境都运行相同版本的 Windows Server 2008 R2 Enterprise,以及相同版本的 IIS 7.5。两者在 IIS 中配置了相同的绑定(所有 IP 地址上的端口 443 和 80)。

我已经检测了代码,可以看到当它工作时,服务正在使用 http 和 https。失败时,仅使用 https。web.config 在两个系统之间是相同的。

我知道,通常,对于 IIS 应用程序中承载的服务,WCF 使用 IIS 中的绑定信息。在这种情况下,将使用 ASP.NET 路由功能。

WCF 如何确定要使用的基址?


更新:下面是 web.config 文件的摘录:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <diagnostics>
      <endToEndTracing propagateActivity="true" activityTracing="true"
       messageFlowTracing="true" />
    </diagnostics>
    <extensions>
      <behaviorExtensions>
        <add name="silverlightFaults" type="Services.SilverlightFaultBehavior, Services" />
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="SilverlightRESTBehavior">
          <webHttp helpEnabled="false" automaticFormatSelectionEnabled="false" 
                   defaultOutgoingResponseFormat="Json" faultExceptionEnabled="false" />
          <silverlightFaults />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="Services.SpendAnalysisService">
        <endpoint address="" behaviorConfiguration="SilverlightRESTBehavior"
          binding="webHttpBinding" contract="Services.SpendAnalysisService" />
        <host> <!-- Added: not in the original-->
          <baseAddresses>
            <add baseAddress="http://" />
            <add baseAddress="https://" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="d" helpEnabled="false" defaultOutgoingResponseFormat="Json"
          automaticFormatSelectionEnabled="false" faultExceptionEnabled="false" />
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>
</configuration>

编辑

另一个提示:“需要 SSL”是在 IIS 的培训环境中设置的,并在集成环境中被清除。在训练环境中清除它可防止服务器端异常。现在,两个环境中的 WCF 日志都显示正在考虑 http 和 https 地址。

现在的问题是:当请求以 https 形式到达时,为什么 WCF 认为它需要 http?

.NET WCF Silverlight Webhttpbinding

评论

0赞 Sixto Saez 10/10/2012
为HTTP和HTTPS定义单独的baseAddresses看起来不对,但我找不到任何具体的东西来说明这是行不通的。您可能希望将您的配置与此 SO 问答进行比较,以确保配置正确。此外,IIS 中的主机标头在各种环境之间可能存在一些差异(以使 SSL 正常工作)。在客户端,hosts 文件中的条目可能因客户端环境而异。
0赞 John Saunders 10/10/2012
单独的基址是一个实验,将被删除,因为它们没有解决问题。绑定中没有指定主机标头。你对主机文件的看法很有趣;你能说说这有什么关系吗?使用了主机文件,我有一种感觉它们可能很重要,但不太明白如何。
0赞 Sixto Saez 10/10/2012
在客户端,如果集成计算机具有与生产环境相似的主机文件,但训练环境计算机不同,则您可能会看到类似的问题。此外,hosts 文件将包含将计算机主地址 (127.0.0.1) 替换为类似 mySecureDomain.org 的条目,仍指向 127.0.0.1,因此 SSL 证书中的域仍有效以启用 HTTPS。
0赞 John Saunders 10/10/2012
谢谢。仅供参考,https 始终在方案列表中。“http”存在于集成中,但不存在于训练中。
0赞 John Saunders 10/10/2012
大提示,但还没有答案:见 msdn.microsoft.com/en-us/library/...

答:

0赞 John Saunders 10/11/2012 #1

这个非常具体的问题的答案很简单:

失败的站点具有 和 的 IIS 绑定。但是,在 IIS 中的“SSL 设置”下设置了“需要 SSL”标志。这是有道理的,因为该站点只能通过SSL访问(一旦负载均衡器设置正确)。这导致 WCF 从其基址搜索中排除 http 方案。清除“需要 SSL”标志解决了问题。httphttps

剩下的问题可能是我创建复制器后 Microsoft 支持的问题:为什么 WCF 甚至要考虑整个请求和所有相关请求都结束了?httphttps

我希望找到一种方法来更通用地重写这个问题,以便答案可以使其他人受益。现在,我很想把这个问题说成是“太本地化了”。