WCF客户端发送的数据已损坏

时间:2012-02-12 13:10:08

标签: wcf

我们在服务器端通过系统诊断配置设置生成的.svclog文件中遇到以下异常。

  

异常:System.ServiceModel.ProtocolException
  消息:可用字节数与HTTP Content-Length不一致   头。可能存在网络错误或客户端可能存在   发送无效请求。

我们观察到WCF客户端发送的数据已损坏。我们通过在WCF客户端生成的.svclog文件中查看消息xml来了解这一点。

实际上,我们通过将数据分成小块来发送大数据,调用WCF服务方法以循环方式发送数据。以下是WCF客户端的相同代码。

DataTable dtStockDetails = new DataTable("StockDetails");
sqlDataAdapter.Fill(dtStockDetails);

int stockDetailsBatchSize = 100;
DataTable dtStockDetailsBatch = dtStockDetails.Clone();
DataRow dr;
int stockDetailsBatchCount = 0;
int stockDetailsTotalRecords = dtStockDetails.Rows.Count;

while (dtStockDetails.Rows.Count > 0)
{
    dr = dtStockDetails.Rows[0];

    dtStockDetailsBatch.ImportRow(dr);
    dtStockDetailsBatch.AcceptChanges();

    dtStockDetails.Rows.Remove(dr);
    dtStockDetails.AcceptChanges();

    if ((dtStockDetailsBatch.Rows.Count == stockDetailsBatchSize) || (dtStockDetails.Rows.Count == 0))
    {
        stockDetailsBatchCount++;
        sendStockDetailsResult = serviceClient.SendStockDetails(dtStockDetailsBatch);
        dtStockDetailsBatch.Clear();
    }
}

现在WCF客户端有时会发送7批数据,有时会发送9批数据,有时会发送10批数据,....在所有情况下,激光消息(数据批处理)xml被破坏。这种行为是随机的。

我们不确定为什么消息xml被破坏并导致通信结束。它从不发送所有批次的数据。

以下是配置设置:

WCF服务配置设置:

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
  <services>
    <service behaviorConfiguration="InventoryServices.InventoryImportServiceBehavior"
      name="InventoryServices.InventoryImportService">
      <endpoint address="https://www.domain.com/InventoryServices/InventoryImportService.svc" behaviorConfiguration="wsServiceEndpointBehavior"
        binding="wsHttpBinding" bindingConfiguration="b1" contract="InventoryServices.IInventoryImportService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      <host>
        <baseAddresses>
          <add baseAddress="https://www.domain.com" />
        </baseAddresses>
      </host>
    </service>
  </services>
  <bindings>
    <wsHttpBinding>
      <binding name="b1" closeTimeout="00:30:00" openTimeout="00:30:00"
        receiveTimeout="00:30:00" sendTimeout="00:30:00" maxReceivedMessageSize="2147483647">
        <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
          maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        <reliableSession inactivityTimeout="00:30:00" />
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="Certificate">
          </transport>
          <message clientCredentialType="UserName" negotiateServiceCredential="true" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="wsServiceEndpointBehavior">
        <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior name="InventoryServices.InventoryImportServiceBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceCredentials>
          <serviceCertificate findValue="XyzClient" x509FindType="FindBySubjectName" />
          <userNameAuthentication userNamePasswordValidationMode="Custom"
            customUserNamePasswordValidatorType="InventoryServices.Helpers.CustomValidator, InventoryServices" />
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

WCF客户端配置设置:

<system.serviceModel>
  <diagnostics>
    <messageLogging logEntireMessage="true" logMalformedMessages="true"
      logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"
      maxSizeOfMessageToLog="2147483647" />
  </diagnostics>
  <bindings>
    <wsHttpBinding>
      <binding name="WSHttpBinding_IInventoryImportService"
          closeTimeout="00:30:00" openTimeout="00:30:00" receiveTimeout="00:30:00"
          sendTimeout="00:30: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:30:00"
            enabled="false" />
        <security mode="TransportWithMessageCredential">
          <transport clientCredentialType="None" proxyCredentialType="None"
              realm="">
            <extendedProtectionPolicy policyEnforcement="Never" />
          </transport>
          <message clientCredentialType="UserName" negotiateServiceCredential="true"
              algorithmSuite="Default" establishSecurityContext="true" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <client>
    <endpoint address="https://www.domain.com/InventoryServices/InventoryImportService.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IInventoryImportService"
            contract="InventoryImportService.IInventoryImportService"
            name="WSHttpBinding_IInventoryImportService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
  </client>
</system.serviceModel>
<system.diagnostics>
  <sources>
    <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing"
      propagateActivity="false">
      <listeners>
        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
          <filter type="" />
        </add>
        <add name="sharedListener">
          <filter type="" />
        </add>
      </listeners>
    </source>
    <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
      <listeners>
        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
          <filter type="" />
        </add>
        <add name="sharedListener">
          <filter type="" />
        </add>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add initializeData="C:\Program Files\InventoryExportUtilitySetup\servicetrace.svclog"
      type="System.Diagnostics.XmlWriterTraceListener" name="sharedListener">
      <filter type="" />
    </add>
  </sharedListeners>
</system.diagnostics>

任何人都可以建议我们应该怎么做才能解决这个问题?

提前致谢。

1 个答案:

答案 0 :(得分:0)

查看您的配置,Server和Client上的Reader Quotas设置是不同的。 确保在客户端和服务器上具有大多数相同的值。

只是想知道您是否尝试过发送任何小的有效负载数据以确保服务正常运行?

我还注意到您已将安全性设置为“TransportWithMessageCredential”,并且您具有mexHttpBinding的mex端点。我想应该是mexHttpsBinding,并且你的httpGetEnabled属性设置为true,因为它应该是httpsGetEnabled为true。