无法跨域传递大量数据
Posted
技术标签:
【中文标题】无法跨域传递大量数据【英文标题】:Unable to pass large amount of data cross domain 【发布时间】:2014-06-29 17:57:57 【问题描述】:我在我的 c# mvc 应用程序中使用 wcf 服务。我需要通过 wcf 到客户端(到控制器)获取大量数据(大约 20000 条记录)。
在本地版本中 - 我可以很好地获取所有记录,但在服务器版本中,如果我不将查询限制为 1000 条记录,我将一无所获。
当它不受限制并试图带来所有记录时,这就是我在客户端日志中得到的:
System.ServiceModel.CommunicationException:发生错误时 接收对 xxx/WCF.svc 的 HTTP 响应。这可能是由于 到不使用 HTTP 协议的服务端点绑定。这 也可能是由于 HTTP 请求上下文被 服务器(可能是由于服务关闭)。查看服务器日志 更多细节。 ---> System.Net.WebException:底层 连接已关闭:接收时发生意外错误。 ---> System.IO.IOException:无法从传输中读取数据 连接:已存在的连接被远程强行关闭 主持人。 ---> System.Net.Sockets.SocketException:现有连接 被远程主机强行关闭 System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区,Int32 偏移量, Int32 大小)---内部异常堆栈跟踪结束---在 System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区,Int32 偏移量, Int32 大小)在 System.Net.PooledStream.Read(Byte[] 缓冲区,Int32 偏移量,Int32 大小)在 System.Net.Connection.SyncRead(HttpWebRequest 请求,布尔值 userRetrievedStream, Boolean probeRead) --- 内部异常结束 堆栈跟踪 --- 在 System.Net.HttpWebRequest.GetResponse() 在 System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout) --- 内部异常堆栈跟踪结束 ---
我已将此添加到客户端的 web.config 中,但没有帮助:
<behaviors>
<endpointBehaviors>
<behavior >
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</endpointBehaviors>
</behaviors>
有什么想法吗?
【问题讨论】:
服务器端的 WCF 跟踪是否显示任何错误? 你为什么不只使用分页并一次请求说 1000 个项目?一次获取所有内容可以说是一个糟糕的设计选择。这是通过 Internet 还是仅仅通过公司 LAN?您仍然可以使用 tcp 进行跨域。如果它是一个局域网,你应该使用 tcpBinding。 J. Lowy,“编程 WCF 服务”,第 3 版 【参考方案1】:您的绑定配置是否设置为允许大数据? 如果您使用的是 httpbinding,您应该以这种方式配置您的端点和服务
<basicHttpBinding>
<binding name="LargeDataBindingConfiguration" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="false">
<readerQuotas maxDepth="32" maxStringContentLength="998192" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
然后尝试在您的服务器上增加 IIS 支持的请求中内容的最大长度
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="4294967295" />
</requestFiltering>
</security>
【讨论】:
虽然这是一个很好的答案,但它通过隐藏症状而不是修复原因来鼓励不良做法 - 在这种情况下,OP 的糟糕设计是一次获取所有内容而不是使用分页。【参考方案2】:正如 Mackho 所说,您应该在第一个配置设置中增加超时时间。此外,客户端必须增加他们的超时值和他们可以从服务器获得的最大内容。
另外,如果您确实需要传递所有数据并且不想使用分页,则可以使用流式传输服务。要将您的服务配置为以流模式运行,请添加:
<bindings>
<basicHttpBinding>
<binding transferMode="Streamed" name="LargeDataBindingConfiguration" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="false">
<readerQuotas maxDepth="32" maxStringContentLength="998192" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
请注意,您的客户端设置也很重要:
以最低超时为准(来自客户端或服务器) 以 maxStringContentLength 与客户端关于他们可以接收多少的设置之间的最低值为准 要使用流式传输,客户端必须支持它并且也具有相同的设置(否则,在客户端上数据将被缓冲)这真的取决于异常是由服务器还是由客户端抛出的。在两者中启用 WCF 跟踪并查看引发异常的位置,然后在该端进行必要的配置。
【讨论】:
以上是关于无法跨域传递大量数据的主要内容,如果未能解决你的问题,请参考以下文章