传输较大的结果集时出现 WCF CommunicationException
WCF CommunicationException when transmitting larger result sets
通过 WCF WebService 访问数据库时发生以下错误:An error (Unable to read data from the transport connection: The connection was closed.) occurred while transmitting data over the HTTP channel.
我正在使用以下测试用例来重现错误。
[TestCase]
public void TestLargeDBs()
{
var cl = new DBUpdaterClient();
var d1 = cl.ExecuteReaderUGV("test", "SELECT * from tblPerson LIMIT 10000");
d1 = cl.ExecuteReaderUGV("test", "SELECT * from tblPerson");
d1 = cl.ExecuteReaderUGV("test", "SELECT * from angebotdetails");
}
第一个结果包含 10k 行,第二个 20k,第三个 225k。该错误可能在任何调用中发生,但有时根本不会发生。起初我认为这与消息长度有关,但现在我不知道问题出在哪里...有人给我一些提示吗?
尽管文件存在并且配置正确,但我认为跟踪不会产生任何输出...
Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true" >
<listeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="nochwas.svclog"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messagelistener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="myMessages.svclog"></add>
</listeners>
</source>
<source name="myUserTraceSource"
switchValue="Information, ActivityTracing">
<listeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="myActivities.svclog"/>
</listeners>
</source>
</sources>
<trace autoflush="true" />
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="Error.svclog" />
</sharedListeners>
</system.diagnostics>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="2147483647" executionTimeout="60"/>
</system.web>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true"
logMessagesAtServiceLevel="false"
logMessagesAtTransportLevel="false"
logMalformedMessages="true"
maxMessagesToLog="5000"
maxSizeOfMessageToLog="2000">
</messageLogging>
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- Legen Sie die Werte unten vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Metadateninformationen zu vermeiden. -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- Damit in Fehlern Ausnahmedetails zum Debuggen angezeigt werden, legen Sie den Wert unten auf "true" fest. Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Ausnahmeinformationen zu vermeiden. -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<!-- Umgeht eine CommunicationException, die auftritt, wenn der ObjectGraph überläuft -->
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IDBUpdater"
closeTimeout="00:10:00"
openTimeout="00:10:00"
receiveTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
messageEncoding="Text"
textEncoding="utf-8"
transferMode="StreamedResponse"
useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<remove scheme="http" />
<add scheme="http" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDBUpdater" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647" />
</requestFiltering>
</security>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
Um das Stammverzeichnis der Webanwendung beim Debuggen auszuwählen, legen Sie den Wert unten auf "true" fest.
Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Informationen über den Webanwendungsordner zu vermeiden.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IDBUpdater"
closeTimeout="00:10:00"
openTimeout="00:10:00"
receiveTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
messageEncoding="Text"
textEncoding="utf-8"
transferMode="StreamedResponse"
useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- Legen Sie die Werte unten vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Metadateninformationen zu vermeiden. -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- Damit in Fehlern Ausnahmedetails zum Debuggen angezeigt werden, legen Sie den Wert unten auf "true" fest. Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Ausnahmeinformationen zu vermeiden. -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<!-- Umgeht eine CommunicationException, die auftritt, wenn der ObjectGraph überläuft -->
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<endpoint address="http://10.1.58.48/DBUpdate/UpdateService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDBUpdater"
contract="DBUpdater.IDBUpdater" />
</client>
</system.serviceModel>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
</configuration>
我几乎阅读了我能找到的有关 WebServices 的 CommunicationExceptions 的所有内容,但我无法让 WebService 以可靠的方式工作而不会崩溃。感谢你们的任何建议!
来自客户端的异常详细信息:
An error (Unable to read data from the transport connection: The connection was closed.) occurred while transmitting data over the HTTP channel. (CommunicationException (IOException))
bei System.ServiceModel.Channels.HttpInput.WebResponseHttpInput.WebResponseInputStream.Read(Byte[] buffer, Int32 offset, Int32 count)
bei System.ServiceModel.Channels.MaxMessageSizeStream.Read(Byte[] buffer, Int32 offset, Int32 count)
bei System.IO.BufferedStream.Read(Byte[] array, Int32 offset, Int32 count)
bei System.Xml.EncodingStreamWrapper.Read(Byte[] buffer, Int32 offset, Int32 count)
bei System.Xml.XmlBufferReader.TryEnsureBytes(Int32 count)
bei System.Xml.XmlBufferReader.GetBuffer(Int32 count, Int32& offset, Int32& offsetMax)
bei System.Xml.XmlUTF8TextReader.ReadText(Boolean hasLeadingByteOf0xEF)
bei System.Xml.XmlUTF8TextReader.Read()
bei System.Runtime.Serialization.XmlSerializableReader.Read()
bei System.Data.DataTextReader.Read()
bei System.Data.XmlDataLoader.LoadColumn(DataColumn column, Object[] foundColumns)
bei System.Data.XmlDataLoader.LoadTable(DataTable table, Boolean isNested)
bei System.Data.XmlDataLoader.LoadData(XmlReader reader)
bei System.Data.DataTable.ReadXmlDiffgram(XmlReader reader)
bei System.Data.DataTable.ReadXml(XmlReader reader, XmlReadMode mode, Boolean denyResolving)
bei System.Data.DataTable.ReadXmlSerializable(XmlReader reader)
bei System.Data.DataTable.System.Xml.Serialization.IXmlSerializable.ReadXml(XmlReader reader)
bei System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadIXmlSerializable(XmlSerializableReader xmlSerializableReader, XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, Boolean isMemberType)
bei System.Runtime.Serialization.XmlDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
bei System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
bei System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
bei System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
...
有几个条目的持续时间不同...有时异常发生在 1 秒后,有时在 9 后,但总是相同的异常。
如果它时而有效,时而无效,那么您真的必须检查服务器和客户端站点的 wcf 日志以确定哪里出了问题。在这种情况下,我怀疑客户。您已经有服务器端的跟踪日志记录,请尝试将其添加到客户端站点并检查客户端和服务器日志中的错误:
启用跟踪(确保目录 c:\log 退出并且您有正确的访问权限):
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "c:\log\Traces.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
在咨询了 Web 服务专家后,他给了我关键字 MTOM (Message Transmission Optimization Mechanism)。一般而言,Web 服务并非设计用于传输大数据集,但通过 MTOM 增强,这是可能的。
我的新 web.config:
<behaviors>
<serviceBehaviors>
<behavior name="svcBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="MTOMBinding"
messageEncoding="Mtom"
closeTimeout="00:10:00"
openTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="svcBehavior" name="DBUpdateService.UpdateService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MTOMBinding" contract="DBUpdateService.IDBUpdater" />
</service>
</services>
app.config(客户端)
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MTOMBinding" 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="2147483647"
messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://xxx/UpdateService.svc"
binding="wsHttpBinding"
bindingConfiguration="MTOMBinding"
contract="UpdateService.IDBUpdater" />
</client>
</system.serviceModel>
我正在使用 wsHttpBinding,但我确信 MTOM 也可以与其他绑定一起使用。我完全删除了所有其他绑定,因为当 basicHttpBinding 也在 web.config 中配置时,客户端和服务器在交换数据时遇到问题。但我相信如果配置正确,那是没有必要的。
我 运行 对包含超过 200k 行的数据表进行了一些测试,Web 服务 运行 多次发送这些数据表并且没有出现 CommunicationException!因此,如果您在使用 Web 服务和大型数据集时遇到问题,请尝试 MTOM!
通过 WCF WebService 访问数据库时发生以下错误:An error (Unable to read data from the transport connection: The connection was closed.) occurred while transmitting data over the HTTP channel.
我正在使用以下测试用例来重现错误。
[TestCase]
public void TestLargeDBs()
{
var cl = new DBUpdaterClient();
var d1 = cl.ExecuteReaderUGV("test", "SELECT * from tblPerson LIMIT 10000");
d1 = cl.ExecuteReaderUGV("test", "SELECT * from tblPerson");
d1 = cl.ExecuteReaderUGV("test", "SELECT * from angebotdetails");
}
第一个结果包含 10k 行,第二个 20k,第三个 225k。该错误可能在任何调用中发生,但有时根本不会发生。起初我认为这与消息长度有关,但现在我不知道问题出在哪里...有人给我一些提示吗?
尽管文件存在并且配置正确,但我认为跟踪不会产生任何输出...
Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true" >
<listeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="nochwas.svclog"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messagelistener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="myMessages.svclog"></add>
</listeners>
</source>
<source name="myUserTraceSource"
switchValue="Information, ActivityTracing">
<listeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="myActivities.svclog"/>
</listeners>
</source>
</sources>
<trace autoflush="true" />
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="Error.svclog" />
</sharedListeners>
</system.diagnostics>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="2147483647" executionTimeout="60"/>
</system.web>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true"
logMessagesAtServiceLevel="false"
logMessagesAtTransportLevel="false"
logMalformedMessages="true"
maxMessagesToLog="5000"
maxSizeOfMessageToLog="2000">
</messageLogging>
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- Legen Sie die Werte unten vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Metadateninformationen zu vermeiden. -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- Damit in Fehlern Ausnahmedetails zum Debuggen angezeigt werden, legen Sie den Wert unten auf "true" fest. Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Ausnahmeinformationen zu vermeiden. -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<!-- Umgeht eine CommunicationException, die auftritt, wenn der ObjectGraph überläuft -->
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IDBUpdater"
closeTimeout="00:10:00"
openTimeout="00:10:00"
receiveTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
messageEncoding="Text"
textEncoding="utf-8"
transferMode="StreamedResponse"
useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<remove scheme="http" />
<add scheme="http" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDBUpdater" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647" />
</requestFiltering>
</security>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
Um das Stammverzeichnis der Webanwendung beim Debuggen auszuwählen, legen Sie den Wert unten auf "true" fest.
Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Informationen über den Webanwendungsordner zu vermeiden.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IDBUpdater"
closeTimeout="00:10:00"
openTimeout="00:10:00"
receiveTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
messageEncoding="Text"
textEncoding="utf-8"
transferMode="StreamedResponse"
useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- Legen Sie die Werte unten vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Metadateninformationen zu vermeiden. -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- Damit in Fehlern Ausnahmedetails zum Debuggen angezeigt werden, legen Sie den Wert unten auf "true" fest. Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Ausnahmeinformationen zu vermeiden. -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<!-- Umgeht eine CommunicationException, die auftritt, wenn der ObjectGraph überläuft -->
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<endpoint address="http://10.1.58.48/DBUpdate/UpdateService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDBUpdater"
contract="DBUpdater.IDBUpdater" />
</client>
</system.serviceModel>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
</configuration>
我几乎阅读了我能找到的有关 WebServices 的 CommunicationExceptions 的所有内容,但我无法让 WebService 以可靠的方式工作而不会崩溃。感谢你们的任何建议!
来自客户端的异常详细信息:
An error (Unable to read data from the transport connection: The connection was closed.) occurred while transmitting data over the HTTP channel. (CommunicationException (IOException))
bei System.ServiceModel.Channels.HttpInput.WebResponseHttpInput.WebResponseInputStream.Read(Byte[] buffer, Int32 offset, Int32 count)
bei System.ServiceModel.Channels.MaxMessageSizeStream.Read(Byte[] buffer, Int32 offset, Int32 count)
bei System.IO.BufferedStream.Read(Byte[] array, Int32 offset, Int32 count)
bei System.Xml.EncodingStreamWrapper.Read(Byte[] buffer, Int32 offset, Int32 count)
bei System.Xml.XmlBufferReader.TryEnsureBytes(Int32 count)
bei System.Xml.XmlBufferReader.GetBuffer(Int32 count, Int32& offset, Int32& offsetMax)
bei System.Xml.XmlUTF8TextReader.ReadText(Boolean hasLeadingByteOf0xEF)
bei System.Xml.XmlUTF8TextReader.Read()
bei System.Runtime.Serialization.XmlSerializableReader.Read()
bei System.Data.DataTextReader.Read()
bei System.Data.XmlDataLoader.LoadColumn(DataColumn column, Object[] foundColumns)
bei System.Data.XmlDataLoader.LoadTable(DataTable table, Boolean isNested)
bei System.Data.XmlDataLoader.LoadData(XmlReader reader)
bei System.Data.DataTable.ReadXmlDiffgram(XmlReader reader)
bei System.Data.DataTable.ReadXml(XmlReader reader, XmlReadMode mode, Boolean denyResolving)
bei System.Data.DataTable.ReadXmlSerializable(XmlReader reader)
bei System.Data.DataTable.System.Xml.Serialization.IXmlSerializable.ReadXml(XmlReader reader)
bei System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadIXmlSerializable(XmlSerializableReader xmlSerializableReader, XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, Boolean isMemberType)
bei System.Runtime.Serialization.XmlDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
bei System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
bei System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract& dataContract)
bei System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
...
有几个条目的持续时间不同...有时异常发生在 1 秒后,有时在 9 后,但总是相同的异常。
如果它时而有效,时而无效,那么您真的必须检查服务器和客户端站点的 wcf 日志以确定哪里出了问题。在这种情况下,我怀疑客户。您已经有服务器端的跟踪日志记录,请尝试将其添加到客户端站点并检查客户端和服务器日志中的错误:
启用跟踪(确保目录 c:\log 退出并且您有正确的访问权限):
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "c:\log\Traces.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
在咨询了 Web 服务专家后,他给了我关键字 MTOM (Message Transmission Optimization Mechanism)。一般而言,Web 服务并非设计用于传输大数据集,但通过 MTOM 增强,这是可能的。
我的新 web.config:
<behaviors>
<serviceBehaviors>
<behavior name="svcBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="MTOMBinding"
messageEncoding="Mtom"
closeTimeout="00:10:00"
openTimeout="00:10:00"
sendTimeout="00:10:00"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="svcBehavior" name="DBUpdateService.UpdateService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MTOMBinding" contract="DBUpdateService.IDBUpdater" />
</service>
</services>
app.config(客户端)
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MTOMBinding" 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="2147483647"
messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://xxx/UpdateService.svc"
binding="wsHttpBinding"
bindingConfiguration="MTOMBinding"
contract="UpdateService.IDBUpdater" />
</client>
</system.serviceModel>
我正在使用 wsHttpBinding,但我确信 MTOM 也可以与其他绑定一起使用。我完全删除了所有其他绑定,因为当 basicHttpBinding 也在 web.config 中配置时,客户端和服务器在交换数据时遇到问题。但我相信如果配置正确,那是没有必要的。
我 运行 对包含超过 200k 行的数据表进行了一些测试,Web 服务 运行 多次发送这些数据表并且没有出现 CommunicationException!因此,如果您在使用 Web 服务和大型数据集时遇到问题,请尝试 MTOM!