29

I've written a WCF web service for consumption by a Silverlight app. Initially, the service only required a basic http binding. We now need to be able to deploy the service for use under both http and https. I've found some settings for web.config that allow me to do this as follows:

<system.serviceModel>
  <behaviors>
    <endpointBehaviors>
      <behavior name="SilverlightFaultBehavior">
        <silverlightFaults />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior name="CxtMappingWebService.CxtMappingWebServiceBehavior">
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="True" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <bindings>
    <basicHttpBinding>
      <binding name="SecureHttpBinding">
        <security mode="Transport" />
      </binding>
      <binding name="BasicHttpBinding">
        <security mode="None" />
      </binding>
    </basicHttpBinding>
  </bindings>
  <services>
    <service name="CxtMappingWebService.CxtMappingWebService" behaviorConfiguration="CxtMappingWebService.CxtMappingWebServiceBehavior">
      <endpoint address="" bindingConfiguration="SecureHttpBinding" binding="basicHttpBinding" contract="CxtMappingWebService.ICxtMappingWebService" behaviorConfiguration="SilverlightFaultBehavior" />
      <endpoint address="" bindingConfiguration="BasicHttpBinding" binding="basicHttpBinding" contract="CxtMappingWebService.ICxtMappingWebService" behaviorConfiguration="SilverlightFaultBehavior" />
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
  </services>
</system.serviceModel>

Unfortunately, however, there's a problem with this.

This web service needs to be deployed to hundreds of our customers' servers, and not all of them will be using https. Deploying it to a server that doesn't have an https binding set up in IIS causes it to fail. Is there a way to have both of these bindings in the web.config by default without it dying if there's not an https binding set up in IIS?

We've got a possible solution for this problem, but it doesn't really fit well with our deployment requirements.

Has anybody else encountered anything like this before, and how did you resolve it?

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
Zann Anderson
  • 4,767
  • 9
  • 35
  • 56

4 Answers4

12

The accepted answer on this page is not of much use if you don't use an installer. The correct answer lies in a later edit by the OP himself, all one needs to do is bind both http and https ports in IIS and then use the configuration below.

            <service name="CxtMappingWebService.CxtMappingWebService" behaviorConfiguration="CxtMappingWebService.CxtMappingWebServiceBehavior">
              <endpoint address="" bindingConfiguration="SecureHttpBinding" binding="basicHttpBinding" contract="CxtMappingWebService.ICxtMappingWebService" behaviorConfiguration="SilverlightFaultBehavior" />
              <endpoint address="" bindingConfiguration="BasicHttpBinding" binding="basicHttpBinding" contract="CxtMappingWebService.ICxtMappingWebService" behaviorConfiguration="SilverlightFaultBehavior" />
              <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            </service>

That worked just fine for me!

  • 1
    Why I try this, I get a ServiceActivationException. ...cannot be activated due to an exception during compilation. The exception message is: Cannot add two items with the same key to SynchronizedKeyedCollection.. ---> System.ArgumentException: Cannot add two items with the same key to SynchronizedKeyedCollection – Alex Dresko May 26 '17 at 14:38
11

In the end, we decided to go with external files using the configSource attribute for the bindings, behaviors, and services sections of the web.config, like so:

<bindings configSource="bindings.config" />
<behaviors configSource="behaviors.config" />
<services configSource="services.config" />

This way, we deploy it by default with those external files set up for http access only, and give the customer instructions (or assist them) on how to edit the external files to set up for https access. This also allows us to deploy future changes to the web.config itself without overwriting the external config files.

Zann Anderson
  • 4,767
  • 9
  • 35
  • 56
  • did you tried any solution for http and https binding? any *.configs for case http-https or only http? – Kiquenet Apr 29 '16 at 10:57
4

This would be handled by the installer you use to deploy the service. It should be a prerequisite (or at least leave an option in the installer) to deploy the both endpoints or only the http one.

Johann Blais
  • 9,389
  • 6
  • 45
  • 65
1

Two of your endpoints have the same URI. This is not permitted in WCF. You should be able to specify endpoints with different bindings, but the URI's must be different (i.e. different port number or different contract).

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
jonnyb
  • 352
  • 1
  • 2
  • 17
  • 1
    That's what I thought until I configured it this way just to see if it would work, and for whatever reason it does, maybe because of the fact that the https binding in IIS is set up for port 443. The only thing that doesn't work is trying to have it run on a machine where IIS doesn't have an https binding set up. – Zann Anderson Jan 25 '11 at 19:32
  • 1
    You actually can have the same address on multiple endpoints because of contract filtering and the distinction between an endpoint address and a listenURI. See [Multiple Endpoints at a Single ListenUri](http://msdn.microsoft.com/en-us/library/aa395210.aspx) for details. – BitMask777 May 15 '13 at 19:16
  • I have this _bindings_ (`(type:hostname:port)`) in IIS: ***http:none hostaname:49759***, ***https:pre.company.es:443*** and ***http:pre.company.es:80***, AND my **URIs** _. ***baseaddress***: _http://preserver:49759/vdir1/SilverlightServices/serv.svc_ and _https://pre.company.es/vdir1/SilverlightServices/serv.svc_ Which would be the **address** ? – Kiquenet Apr 29 '16 at 10:47