How to configure a single WCF Service to have multiple HTTP and HTTPS endpoints?

What I am trying to do is get a SINGLE WCF Service to work in the development environment which is the HTTP scheme, and, also, have the SAME service work in the production environment which is the HTTPS scheme. If I remove the two Https endpoints (those suffixed 'Https'), it works in the development enviornment; likewise, if I remove only the two Http endpoints then it works in the production environment. I would like to have all four endpoints in the web.config, if possible.

My endpoints are defined below:

<endpoint address="/Web" 
        behaviorConfiguration="AjaxBehavior"
        binding="wsHttpBinding" 
        bindingConfiguration="web" 
        name="Web"
        contract="Service" />
<endpoint address="/Custom"
        binding="customBinding" 
        bindingConfiguration="custom" 
        name="Custom"   
        contract="Service" />
<endpoint 
        address="/WebHttps" 
        behaviorConfiguration="AjaxBehavior"
        binding="wsHttpBinding" 
        bindingConfiguration="webHttps" 
        name="WebHttps"
        contract="Service" />
<endpoint address="/CustomHttps"
        binding="customBinding" 
        bindingConfiguration="customHttps" 
        name="CustomHttps" 
        contract="Service" />

Edited: I am editing my question to add the error I am getting, and the binding sections (below). Sorry for the new length of the question.

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

Additionally, the production site is set up to "Require SSL". That can not change.

The bindings configurations are:

<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"  />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="AjaxBehavior">
      <enableWebScript/>
    </behavior>
  </endpointBehaviors>
</behaviors>

<bindings>
  <customBinding>
    <binding name="custom">
      <textMessageEncoding>
        <readerQuotas maxDepth="7000000" maxStringContentLength="7000000"
            maxArrayLength="7000000" maxBytesPerRead="7000000"
            maxNameTableCharCount="7000000" />
      </textMessageEncoding>

      <httpTransport maxBufferPoolSize="7000000" maxReceivedMessageSize="7000000"
          maxBufferSize="7000000" />
    </binding>
    <binding name="customHttps">
      <textMessageEncoding>
        <readerQuotas maxDepth="7000000" maxStringContentLength="7000000"
            maxArrayLength="7000000" maxBytesPerRead="7000000"
                  maxNameTableCharCount="7000000" />
      </textMessageEncoding>

      <httpsTransport maxBufferPoolSize="7000000" maxReceivedMessageSize="7000000"
          maxBufferSize="7000000" />

    </binding>
  </customBinding>

  <webHttpBinding>
    <binding name="web"  maxBufferPoolSize="70000000"
        maxReceivedMessageSize="70000000">
      <readerQuotas maxDepth="70000000" maxStringContentLength="70000000"
          maxArrayLength="70000000" maxBytesPerRead="70000000"
          maxNameTableCharCount="70000000" />
      <security mode="None" />
    </binding>

    <binding name="webHttps" maxBufferPoolSize="70000000"
        maxReceivedMessageSize="70000000">

      <readerQuotas maxDepth="70000000" maxStringContentLength="70000000"
                maxArrayLength="70000000" maxBytesPerRead="70000000"
                maxNameTableCharCount="70000000" />

      <security mode="Transport" />
    </binding>
  </webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

Any ideas?

Answers


Follow these steps-

1) Write two endpoints for the service, one is for http and another for https.

<services>
    <service behaviorConfiguration="MyServiceBehavior" name="JK.MyService">

      <endpoint address="" behaviorConfiguration="WebBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="JK.IMyService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>

      <endpoint address="" behaviorConfiguration="WebBehavior" binding="webHttpBinding" bindingConfiguration="webBindingHTTPS" contract="JK.IMyService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>     

    </service>
  </services>

2) Enable both httpGetEnabled="True" httpsGetEnabled="true" in serviceBehaviors.

<behaviors>

<serviceBehaviors>      
  <behavior name="MyServiceBehavior">
    <serviceMetadata httpGetEnabled="True" httpsGetEnabled="true"/>
    <serviceDebug includeExceptionDetailInFaults="true" />
  </behavior>      
</serviceBehaviors>

<endpointBehaviors>
  <behavior name="WebBehavior">
    <webHttp/>
  </behavior>
</endpointBehaviors>

</behaviors>

3) Write two bindings configurations for http and https. For http give security mode="None" and for https give mode="Transport".

<bindings>
    <webHttpBinding>

      <binding name="webBinding">
        <security mode="None">
          <transport clientCredentialType="None" />
        </security>
      </binding>

      <binding name="webBindingHTTPS">
        <security mode="Transport">
          <transport clientCredentialType="None" />
        </security>
      </binding>

    </webHttpBinding>
  </bindings>

Check this link


If you're using Visual Studio 2010 and Web Application Project Deployment you can use the Web.config Transformation Syntax to point your service endpoint's bindingConfiguration to an https enabled binding configuration.

For me, I figured out I only had to replace two elements in the Web.config file. The endpoint's bindingConfiguration attribute and serviceMetadata's httpsGetEnabled should be set to true.

Here's the Web.config, in its default (debug) configuration:

<service name="Service"
            behaviorConfiguration="DefaultBehavior">
    <endpoint name="ServiceEndpoint"
                binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding"
                contract="IService" />
    </service>
    ...
    <behaviors>
    <serviceBehaviors>
        <behavior name="DefaultBehavior">
            <serviceMetadata httpGetEnabled="True" />
            <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
    </serviceBehaviors>
</behaviors>

Here's the Web.Release.config transformation file

<behaviors>
    <serviceBehaviors>
        <behavior>
            <serviceMetadata httpsGetEnabled="True" xdt:Transform="Replace" />
            <serviceDebug includeExceptionDetailInFaults="False" xdt:Transform="SetAttributes(includeExceptionDetailInFaults)"/>
        </behavior>
    </serviceBehaviors>
</behaviors>
<services>
    <service>
        <endpoint bindingConfiguration="SecureTransportBinding"
                    xdt:Transform="SetAttributes(bindingConfiguration)"/>
    </service>
</services>

Here's what my bindings look like, but they are pretty standard. notice the names that are used above:

<basicHttpBinding>
    <binding name="SecureTransportBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
        <security mode="Transport"/>
        <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
    </binding>
    <binding name="BasicHttpBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2147483647">
        <security mode="None"/>
        <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
    </binding>
</basicHttpBinding>

Here's a link to more about Web.config transformations:

http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx


There are lots of reasons you can get the error:

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

Most of the reasons are from the Web.config settings, but it could be from IIS. I had the same problems, if you defended Endpoints with both http and https bindings, you have to create http and https binding for the website you created in IIS->Site->Bindings, otherwise you will get this error.


This is one reason why you can setup binding from configuration: To be able to use different settings in different environments.

The easiest solution for you is to use makecert to create test certificate for your development environment and use HTTPS on both development and production machine.

Another solution is to create installation package (msi) and let admin change enpoint setting during installation.

Edit:

Your requirement of having all 4 endpoints on both machines is achievable but in that case your service will be also exposed on HTTP in production and everybody who will have WSDL for the service will know about that.


The default receive timeout is 10 minutes, so WCF client will be disconnected after the idle time exceeded that limitation. What can I do if the connection needs to be kept alive?

Solution #1:

Server provides a dummy operation for client calls it regularly to let it not idle.

Solution #2:

Enable reliableSession and set receiveTimeout and inactivityTimeout to “infinite” in both the client and server. The configuration snippet may like the following:

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="WSHttpBinding" receiveTimeout="infinite">
        <reliableSession inactivityTimeout="infinite" enabled="true" />
      </binding>
    </wsHttpBinding>
  </bindings>
  <services>
  ...
  </services>
  ...
</system.serviceModel>

Need Your Help

How can I check the bundle version of our application programmatically?

iphone

I have made an application and I have installed it on my iphone, but I want to check my application bundle version programatically. How can that be done?

Loop Java HashMap like Python Dictionary?

java python hashmap equivalent

In Python, you can have key,value pairs in a dictionary where you can loop through them, as shown below: