views:

72

answers:

3

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:




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

A: 

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.

Ladislav Mrnka
Can't use Self-Signed certificates because I need to use the VS Development Server. This is a viable solution, but it would be my last resort. Right now, I'm thinking of using a ServiceHostFactory and building all the bindings and end points dynamically from a config section. I'm frustrated with WCF
Breakskater
You are frustrated because you are using VS Development server which does not support most of WCF features. WCF is not source of your frustration. Bad tools are.
Ladislav Mrnka
I agree. Visual Studio Development Server should support HTTPS. It would make for a better test/debug environment if it did. I am mainly frustrated at VSDS. I would only have to have a configuration for the HTTPS scheme if VSDS supported it. <sigh>
Breakskater
A: 

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

Vinay B R
Vinay, thanks for you suggestion. I tried it, and I received the error in my new edited question. I posted my binding configuration for review. Additionally, the production site is set up to "Require SSL". That can not change.
Breakskater
Your endpoints specify a relative address for the endpoints, which means they will all use the same base address, which will have to specify either http or https. You could change the endpoint addresses to be absolute (instead of '/web' make it say 'http:/myurl.com/web' and that should fix your error.
Steve Ellinger
A: 

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

Jinkinz