Search code examples
c#.netwcfiiswcf-hosting

WCF Service returns Error when invoking method from client after changing from http to https "ContractFilter mismatch at the EndpointDispatcher"


I created a HTTP wcf service that will be consumed by a windows client and utilized. I had no issue until I was using HTTP. Now my customer wants to change the site to HTTPS. So for development purpose I have used IIS express certificate and setup the service. Now my service is up and running in IIS with iisexpress self signed certificate. I am able to browse my new https service via browser as well as wcf test client tool.

But when I try invoke the method from my windows application to new https wcf service. My service instance is created but only during invoking a method I get following error:

System.ServiceModel.ActionNotSupportedException was unhandled by user code HResult=-2146233087 Message=The message with Action 'http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

In service my binding config (config 3 is being used at https mode and config 2 was used during http mode) are as follows:

    <bindings>
  <wsHttpBinding>
    <binding name="wsHttpBinding_IPGPService">
      <!--config test 1 - start -->
      <!--<security mode="None">
        <transport clientCredentialType="None" />
        <message establishSecurityContext="false" />
      </security>-->
      <!--config test 1 - end -->
      <!--config test 2 - start -->
      <!--<security mode="None" />
            <reliableSession enabled="true" />-->
      <!--config test 2 - end -->
      <!--config test 3 - start -->
      <!--<security mode="Transport">            
        <transport clientCredentialType="None" proxyCredentialType="None"/>
        <message clientCredentialType="Certificate" algorithmSuite="Default" />
      </security>-->
      <security mode="Transport">            
        <transport clientCredentialType="None"/>
      </security>
      <!--config test 3 - end -->
    </binding>
  </wsHttpBinding>
</bindings>

<services>
  <service name="PGPService.PGPService">
    <endpoint address="" binding="wsHttpBinding" contract="PGPService.IPGPService" bindingConfiguration="wsHttpBinding_IPGPService" />
    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />      
  </service>      
</services>



  <serviceBehaviors>
    <behavior>
      <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
      <!--<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> -->
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <!--<serviceDebug includeExceptionDetailInFaults="false"/>-->
      <!--test config - start-->
      <serviceDebug includeExceptionDetailInFaults="True" />
      <!--test config - end-->
    </behavior>
  </serviceBehaviors>
</behaviors>
<protocolMapping>
    <add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>    
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

In client we use custom binding to create service instance.

                        url = "https://localhost:550/TestService/TestService.svc";
                    customBinding = new CustomBinding();
                    customBinding.Elements.Add(new ReliableSessionBindingElement());
                    customBinding.Elements.Add(new HttpsTransportBindingElement());
                    EndpointAddress endpointAdress = new EndpointAddress(url);
                    pgpServiceClientInstance = new PGPServiceClient(customBinding, endpointAdress);
                    pgpServiceClientInstance.ClientCredentials.ClientCertificate.SetCertificate(
                        StoreLocation.CurrentUser,
                        StoreName.Root,
                        X509FindType.FindByThumbprint,
                        ‎"03815c894b62dcf2d17336ade2d9ca61ddb7f92c");

After adding service reference the app.config generated on my Windows application is as follows:

        <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IPGPService">
                <security mode="Transport">
                    <transport clientCredentialType="None" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://localhost:550/TestService/TestService.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IPGPService"
            contract="PGPServiceReference.IPGPService" name="WSHttpBinding_IPGPService" />
    </client>

So now I can see my service instance is getting successfully created. but on the time of invoking a method I get above error.

There is no code changed before and after moving to https on service end. It is the same service code. It was completely working fine on http but is broken on https.

I have completely removed the service reference and added it newly after making my wcf service https. IIS express self signed certificate is installed and available already on my system. Both service and client are running in same system as of now since it is development

I am suspecting I am having a configuration problem....but with less experience I could not figure out.


Solution

  • Actually it was an additional binding during service instantiation that was causing the problem. Got it sorted by commenting below line in instantiation part.

     url = "https://localhost:550/TestService/TestService.svc";
                    customBinding = new CustomBinding();
                    //customBinding.Elements.Add(new ReliableSessionBindingElement());
                    customBinding.Elements.Add(new HttpsTransportBindingElement());
    

    This helped me to proceed with developing the entire service and client. So that concludes my fix for above issue.

    Further down the lane since i am a newbie to wcf service i faced following problems which i faced and solved. Someone who is struggling like me can use below step if you are facing my errors

    1. Next my service had problems accessing folder Fix: add seperate application pool with an service or administrator account with enough privileges.

    2. To add wcf session to existing code. Fix: This is where i am facing problem because i was using wshttpbinding with transport security. Then after browsing several materials and codes understood i have to make my config to custombinding with reliablesession and httpstransport to proceed further with development. so my config roughly appears as

      <customBinding abc of wcf>
        <reliableSession/>
        <httpsTransport/>
      <\customBinding>
      

    And also uncommented above line of service instantiation after understanding its real purpose.No need for any values in reliable session tag and httpsTransport for basic support of security.

    This solved my second issue.

    1. However i am facing wsdl import error in wcf client test tool now which i am struggling now to solve. svcutil proxy generation option or add service refrence with uncheked assembly option doesnt seem to be working. Also i noticed that even if add my service refrence freshly to client there is no configurations generated to my app.config file surprisingly.....and above mentioned options dont help.....looking for experts ideas.... Fix : ??? Expolring.... Souls who read this are welcome to give answer/suggestion.