Tom
Tom

Reputation:

WCF contract mismatch problem

I have a client console app talking to a WCF service and I get the following error: "The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error."

I think it's because of a contract mismatch but i can't figure out why. The service runs just fine by itself and the 2 parts were working together until i added the impersonation code.

Can anyone see what is wrong?

Here is the client, all done in code:

NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

EndpointAddress endPoint = new EndpointAddress(new Uri("net.tcp://serverName:9990/TestService1"));
ChannelFactory<IService1> channel = new ChannelFactory<IService1>(binding, endPoint);
channel.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
IService1 service = channel.CreateChannel();

And here is the config file of the WCF service:

<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="MyBinding">
          <security mode="Message">
            <transport clientCredentialType="Windows"/>
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFTest.ConsoleHost2.Service1Behavior">
          <serviceMetadata httpGetEnabled="true"  />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceAuthorization impersonateCallerForAllOperations="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="WCFTest.ConsoleHost2.Service1Behavior"
          name="WCFTest.ConsoleHost2.Service1">
        <endpoint address="" binding="wsHttpBinding" contract="WCFTest.ConsoleHost2.IService1">
          <identity>
            <dns value="" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <endpoint binding="netTcpBinding" bindingConfiguration="MyBinding"
            contract="WCFTest.ConsoleHost2.IService1" />
        <host>
          <baseAddresses>
            <add baseAddress="http://serverName:9999/TestService1/" />
            <add baseAddress="net.tcp://serverName:9990/TestService1/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Upvotes: 18

Views: 52524

Answers (5)

Varun Bedi
Varun Bedi

Reputation: 41

I was having a similar issue. After spending a mind bending 2 hours on this and trying to find an answer online, I decided to follow the approach to seralize and deserialize the return value/object on the server side using the System.Runtime.Serialization.DataContractSerializer and finally found that I had missed to add EnumMember attribute on one of the Enums.

You may be facing a similar issue.

Here is the code snippet that helped me resolve the issue:

      var dataContractSerializer = new System.Runtime.Serialization.DataContractSerializer(typeof(MyObject));
      byte[] serializedBytes;
        using (System.IO.MemoryStream mem1 = new System.IO.MemoryStream())
        {
            dataContractSerializer.WriteObject(mem1, results);
            serializedBytes = mem1.ToArray();
        }

        MyObject deserializedResult;
        using (System.IO.MemoryStream mem2 = new System.IO.MemoryStream(serializedBytes))
        {
            deserializedResult = (MyObject)dataContractSerializer.ReadObject(mem2);
        }

Upvotes: 3

sivaprakash
sivaprakash

Reputation: 167

If you have two methods with same name and parameters in your WCF it will throw this error

Upvotes: 0

Simon_Weaver
Simon_Weaver

Reputation: 146000

Other possible causes:

  • Trying to serialize an object without a default constructor.
  • Trying to serialize some other kind of non serializable object (such as an Exception). To prevent the item from being serialized apply [IgnoreDataMember] attribute to the field or property.
  • Check your enum fields to make sure they are set to a valid value (or are nullable). You may need to add a 0 value to the enum in some cases. (not sure about fine details of this point).

What to test:

  • Configure WCF tracing for at least critical errors or exceptions. Be careful to watch filesize if you enable any further traces. This will give some very useful information in many cases.

    Just add this under <configuration> in your web.config ON THE SERVER. Create the log directory if it doesn't exist.

 <system.diagnostics>
     <sources>
       <source name="System.ServiceModel"
               switchValue="Error, Critical"
               propagateActivity="true">
         <listeners>
           <add name="traceListener"
               type="System.Diagnostics.XmlWriterTraceListener"
               initializeData= "c:\log\WCF_Errors.svclog" />
         </listeners>
       </source>
     </sources>
   </system.diagnostics>
  • Make sure the .svc file will actually come up in a browser without error. This will give you some 'first chance' help. For instance if you have a non serializable object you'll get this message below. Note that it clearly tells you what can't be serialized. Make sure you have 'mex' endpoint enabled and bring up the .svc file in your browser.

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior contract: http://tempuri.org/:IOrderPipelineService ----> System.Runtime.Serialization.InvalidDataContractException: Type 'RR.MVCServices.PipelineStepResponse' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.

Upvotes: 33

Tom
Tom

Reputation:

Ok, i've just changed the client so it uses a config file instead of code and I get the same error!

Code:

ServiceReference1.Service1Client client = new WCFTest.ConsoleClient.ServiceReference1.Service1Client("NetTcpBinding_IService1");    
client.PrintMessage("Hello!");

Here is the config file of the client, freshly generated from the Service ... which makes my think that it mightn't be a contract mismatch error

<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IService1" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                    hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                    maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
                    maxReceivedMessageSize="65536">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
            </netTcpBinding>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://servername:9999/TestService1/" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="WSHttpBinding_IService1">
                <identity>
                    <dns value="&#xD;&#xA;          " />
                </identity>
            </endpoint>
            <endpoint address="net.tcp://serverName:9990/TestService1/" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IService1" contract="ServiceReference1.IService1"
                name="NetTcpBinding_IService1">
                <identity>
                    <userPrincipalName value="MyUserPrincipalName " />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Upvotes: 1

Paul D
Paul D

Reputation: 81

For me, this error message was thrown because my the web.config Service Behavior by default has a low message limit, so when the WCF returned say 200000 bytes and my limit was 64000 bytes the response was truncated and thus you get the "... not meaningful reply". It's meaningful, it's just been truncated and can't be parsed.

I'll paste my web.config change that fixed the issue:

<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="YourNameSpace.DataServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
      <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      <serviceTimeouts transactionTimeout="05:05:00" />
      <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500"
       maxConcurrentInstances="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>

The maxItemsInObjectGraph value is the most important!
I hope this helps anyone.

Upvotes: 8

Related Questions