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?