11

I'm migrating an existing service from HTTP (Dev/UAT) to HTTPS (Production), and I'm having trouble with the configuration. Here is the system.serviceModel section of my web.config:

<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
    <services>
      <service name="MyService">
        <endpoint name="MyEndpoint" address="" binding="wsHttpBinding"
            bindingConfiguration="secureBinding" contract="IMyService" />
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="secureBinding">
          <security mode="Transport"></security>
        </binding>
      </wsHttpBinding>
    </bindings>
</system.serviceModel>

I've tried this using both basicHttpBinding and wsHttpBinding, with the same results:

  • I can call the service from my SOAP client using http://server.domain.com/MyService.svc
  • I can hit the service from a browser using https://server.domain.com/MyService.svc
  • I can't call the service from my SOAP client using https://server.domain.com/MyService.svc - the call always errors with 404: not found.

My https site is certified using a certificate that was issued by a CA on the corporate domain, and I've verified that I have that CA's certificate installed in Trusted Root Certification Authorities on the system from which I'm making the calls.

The relevant client code:

Service service = new Service();
service.Url = "http://server.domain.com/MyService.svc";
//service.Url = "https://server.domain.com/MyService.svc";
service.WebMethodCall();

EDIT

Here are the requested portions of the WSDL:

<wsdl:types/>
<wsdl:portType name="IMyService"/>
<wsdl:binding name="BasicHttpBinding_IMyService" type="tns:IMyService">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
</wsdl:binding>
<wsdl:service name="MyService">
    <wsdl:port name="BasicHttpBinding_IMyService" 
        binding="tns:BasicHttpBinding_IMyService">
        <soap:address location="http://server.domain.com/MyService.svc"/>
    </wsdl:port>
</wsdl:service>

EDIT

More information:

When I change the serviceMetadata element to have httpGetEnabled="false" and httpsGetEnabled="true" the .svc page shows me the following link:

https://boxname.domain.com/MyService.svc?wsdl

rather than the expected

https://server.domain.com/MyService.svc?wsdl
Matt Mills
  • 8,692
  • 6
  • 40
  • 64
  • If you generate WSDL for your service in production does it include HTTPS port? – Ladislav Mrnka Oct 06 '10 at 21:29
  • I'll add a note about the WSDL in an edit – Matt Mills Oct 06 '10 at 21:33
  • That is expected because your serviceMetadata enables only httpGet and not httpsGet. Also you can't get service reference because you don't expose mex endpoint. The important is content of WSDL when you access it through HTTP - especially the last part describing service and ports. – Ladislav Mrnka Oct 06 '10 at 21:50

4 Answers4

11

Check that your service element name in the web.config matches the fully qualified named of the class that implements your contract.

<services>
  <service name="MyNamespace.MyService">
    <endpoint name="MyEndpoint" address="" binding="wsHttpBinding" ...
Johann Blais
  • 9,389
  • 6
  • 45
  • 65
  • This turned out to be the problem I was having - after I updated the service name value, the https endpoints started showing up in my WSDL. I had to set the host header in IIS for the site to get the *correct* endpoints, but they did show up. – Matt Mills Oct 07 '10 at 15:40
3

In your WSDL you see that your service does not expose port on HTTPS but only on HTTP. Moreover you can also see that your service uses BasicHttpBinding (see port name and binding name). That means that your service configuration is not used at all. Check that name in the service element is same as name in your .svc markup. It has to be defined including namespaces.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • If I change the name in the `Service` attribute of the `ServiceHost` directive in the .svc file, or if I change the `name` attribute of the `service` element in the web.config, I immediately get a yellow screen that says the named service cannot be found. Is there something wrong with my `endpoint` declaration? – Matt Mills Oct 07 '10 at 01:29
  • In fact, changing *any* of the parts of the `endpoint` causes it to break. It's obviously parsing the web.config file; is it really not using it? – Matt Mills Oct 07 '10 at 01:57
0

HTTP and HTTPS are served from different virtual hosts. Are you sure your service is correctly installed in both?

Yuliy
  • 17,381
  • 6
  • 41
  • 47
  • What do you mean? I've got one web site with two bindings on it: `http://server.domain.com` and `https://server.domain.com`. – Matt Mills Oct 06 '10 at 21:32
  • Ah, ok. That's odd. Does running Fiddler or something else to capture traffic yield anything interesting? (What do the server's access logs show?) – Yuliy Oct 06 '10 at 21:37
  • Fiddler shows that the request went across, but it can't show me anything interesting because of the encryption. Where can I see the traffic logs for IIS? – Matt Mills Oct 06 '10 at 21:42
0

Thanks to Johann Blais for the answer, I've found out that you would need to include the fully qualified name for the class that defines the service contract.

For example if your service is

namespace MyCompany.WcfService
{

    [ServiceContract(Namespace="http://xsd.mycompany.com/mcy/1_0_0")]
    public interface IService
    {
        [OperationContract(IsOneWay = false)]
        void DoStuff()
    }

    public class Service : IService
    {
        void DoStuff()
        {
        }
    }
}

The corresponding service definition in your web.config would be

<system.serviceModel>
    <services>
        <service name="MyCompany.WcfService.IService">
            <endpoint address="" binding="basicHttpBinding" contract="MyCompany.WcfService.IService" />
        </service>
    </services>
    ...
</system.serviceModel>