Question

I have a WCF service used by some Silverlight code in our web application. It uses the ASP.NET Routing functionality:

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

This currently works in our Production environment.

On some other environments, I get the exception

System.InvalidOperationException: Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [https].

I have just deployed the exact same code to our Integration environment and to our Training environment. It works in Integration, but fails in Training. Both environments are running the same version of Windows Server 2008 R2 Enterprise, with the same version of IIS 7.5. Both have the same bindings configured in IIS (ports 443 and 80 on all IP addresses).

I have instrumented the code and can see that when it works, both http and https are being used by the service. When it fails, only https is used. The web.config is identical between the two systems.

I know that, in general, with a service hosted in an IIS application, WCF uses the binding information in IIS. In this case, the ASP.NET routing feature is being used.

How does WCF determine which base addresses to use?


Update: Here's an excerpt of our web.config file:

<?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>

Edit:

Another hint: "SSL Required" was set in IIS in the Training environment, and was cleared in the Integration environment. Clearing it in the Training environment prevents the server-side exception. Now, the WCF logs in both environments show that both http and https addresses are being considered.

The question will now be: why does WCF think it needs http when the request arrives as https?

Was it helpful?

Solution

The answer for this very specific question is simple enough:

The failing sites had IIS bindings for both http and https. However, the "Require SSL" flag under "SSL Settings" in IIS was set. This made sense, as the site is only meant to be accessed via SSL (once the load balancer gets set up properly). This was causing WCF to exclude the http scheme from its search for base addresses. Clearing the "Require SSL" flag solved the problem.

The remaining question is probably a question for Microsoft Support once I get a reproducer created: why in the world is WCF even thinking about http since the entire request and all related requests are coming in over https?

I hope to find a way to rewrite this question a bit more generically, so that the answer can benefit someone else. Right now, I'm tempted to close this question as "Too localized".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top