Подтвердить что ты не робот

Проблема несоответствия контракта WCF

У меня есть клиентское консольное приложение, говорящее с сервисом WCF, и я получаю следующую ошибку: "Сервер не предоставил значимого ответа, это может быть вызвано несоответствием контракта, преждевременным отключением сеанса или внутренней ошибкой сервера".

Я думаю, это из-за несоответствия контракта, но я не могу понять, почему. Служба работает просто отлично сама по себе, и две части работали вместе, пока я не добавил код олицетворения.

Кто-нибудь может понять, что не так?

Вот клиент, все сделано в коде:

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();

И вот конфигурационный файл службы WCF:

<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>
4b9b3361

Ответ 1

Другие возможные причины:

  • Попытка сериализации объекта без конструктора по умолчанию.
  • Попытка сериализовать другой тип несериализуемого объекта (например, исключение). Чтобы предотвратить сериализацию элемента, примените атрибут [IgnoreDataMember] к полю или свойству.
  • Проверьте свои поля перечисления, чтобы убедиться, что они установлены на допустимое значение (или являются нулевыми). Возможно, вам придется добавить значение 0 в перечисление в некоторых случаях. (не уверен в деталях этой точки).

Что тестировать:

  • Настроить трассировку WCF для, по крайней мере, критических ошибок или исключений. Будьте внимательны при просмотре файлов, если вы включите дальнейшие следы. Это даст очень полезную информацию во многих случаях.

    Просто добавьте это под <configuration> в web.config НА СЕРВЕРЕ. Создайте каталог log, если он не существует.

 <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>
  • Убедитесь, что файл .svc действительно появится в браузере без ошибок. Это даст вам "первый шанс". Например, если у вас есть несериализуемый объект, вы получите это сообщение ниже. Обратите внимание, что в нем четко указано, что не может быть сериализовано. Убедитесь, что конечная точка "mex" включена, и запустите файл .svc в своем браузере.

ExceptionDetail, вероятно, созданный IncludeExceptionDetailInFaults = истина, значение которого:     System.InvalidOperationException: Исключение было вызвано вызовом Расширение экспорта WSDL: System.ServiceModel.Description.DataContractSerializerOperationBehavior      контракт: http://tempuri.org/:IOrderPipelineService---- > System.Runtime.Serialization.InvalidDataContractException: Тип 'RR.MVCServices.PipelineStepResponse' не может быть сериализована. Рассмотрите маркировку это с DataContractAttribute атрибута и маркировки всех его членов, которых вы хотите сериализовать с помощью Атрибут DataMemberAttribute.

Ответ 2

Для меня это сообщение об ошибке было отправлено, потому что мое поведение по умолчанию для Web.config по умолчанию имеет ограничение на нижний предел, поэтому, когда возвращаемый WCF говорит 200000 байт, а мой предел составляет 64000 байт, ответ был усечен, и, таким образом, вы получаете "... незначительный ответ". Он имеет смысл, он просто усечен и не может быть проанализирован.

Я вставлю свое изменение в web.config, исправив проблему:

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

Значение maxItemsInObjectGraph является самым важным!
Надеюсь, это поможет любому.

Ответ 3

У меня была аналогичная проблема. После того, как я потратил на это 2 часа на размышление и попытался найти ответ в Интернете, я решил следовать подходу к серализации и десериализации возвращаемого значения/объекта на стороне сервера с помощью System.Runtime.Serialization.DataContractSerializer и, наконец, обнаружил, что я пропустил добавить атрибут EnumMember в один из Enums.

У вас может возникнуть аналогичная проблема.

Вот фрагмент кода, который помог мне решить проблему:

      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);
        }

Ответ 4

Хорошо, я только что изменил клиент, поэтому вместо кода используется файл конфигурации, и я получаю ту же ошибку!

код:

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

Вот конфигурационный файл клиента, только что сгенерированный службой..., что заставляет меня думать, что это может быть ошибка несоответствия контракта

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

Ответ 5

Если у вас есть два метода с одинаковыми именами и параметрами в вашем WCF, он выкинет эту ошибку