底层连接已关闭:连接意外关闭。

16

这个异常经常在一个SOAP请求中抛出,该请求接收需要近三分钟并且大小为2.25兆字节。

当我搜索网络时,我发现所有的帖子似乎都是关于在请求上设置头信息,有些要求我不发送“Expect:”头,有些要求我发送“Keep-Alive:”头,但是无论我发送哪些头信息,我仍然会遇到这个烦人的错误。我不认为设置任何头信息就能解决问题,因为我可以使用“curl”重新创建完全相同的请求,并且最终得到了没有任何问题的响应

我的<httpRuntime maxRequestLength="409600" executionTimeout="900"/>

我觉得我已经没有其他选择了。如果有人能提供任何帮助,我将不胜感激。还有一些需要注意的事项是,我请求数据的服务器不在我的控制范围内,而且这些请求是通过https进行的,其他响应较小的请求工作得非常好。

谢谢


我相信这个问题与负载均衡服务器有关。 - David
10个回答

11

你标记了这篇文章为.NET35,那么你正在使用WCF吗?

如果是的话,下面是我们在处理大数据集时使用的App.config示例:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="32" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:1602/EndPoint.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding" contract="IEndPointContract" name="EndPoint" behaviorConfiguration="EndpointBehaviour" />     
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="EndpointBehaviour">
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

2
不,我想我可能会考虑转换为WCF... 我认为原始代码是从一个在2.0或甚至1.1中编写的试点移植过来的。 - David

6
我希望现在回答这个问题还不算太晚。

Try adding the following attribute on the definition of your contract interface:

[ServiceKnownType(typeof(ReturnClass))]

如果您需要返回多态类的通用解决方案,请参考此文章: http://www.goeleven.com/blog/entryDetail.aspx?entry=45


4
如果您使用的是dbml而不是edmx,那么您会收到此错误信息(底层连接已关闭: 连接意外关闭)。因为dbml不会返回可序列化数据,它需要使用datacontract。请转到dbml文件的属性并将Serialization mode更改为单向。

这解决了我的问题,谢谢sharmaja!还有一点需要注意:我必须在客户端更新我的服务引用才能使其工作。希望这能帮助到其他处于同样情况的人。 - Steve J

3
我遇到了同样的问题,经过深入调查,我找到了这篇文章:

Merrick Chaffer's Blog

它与为客户端和服务器设置"dataContractSerializer"有关。希望这对你有所帮助。

3
你尝试过这篇博客文章中提出的建议吗?问题很可能出现在.NET的TCP/HTTP堆栈实现中。

是的,我尝试过了,但没有成功,对我来说它似乎只是设置了一个“Connection: Keep-Alive”的头部。 - David
2
所以你需要调试一下 .NET 的 HTTP/TCP 栈实际在做什么。特别是与 curl 相比,它做错了什么。你应该在 SOAP 请求和服务器之间放置 Wireshark(TCP 网络嗅探器)或 Fiddler(HTTP 代理)。这样你就能够发现差异了。 - mkoeller
好的,我已经将“Web服务”转换为WCF服务,如果这还没起作用,我会尝试这个,但需要调查如何更好地从wireshark过滤结果... 或者也许Fiddler更好用。 - David
1
Fiddler通常更适用于HTTP调试。然而,有时需要进行TCP级别的分析。你是否注意到Wireshark中的“跟随TCP流”功能?那可以节省相当多的时间。 - mkoeller
没有注意到,我一定会去看看的,谢谢! - David

3

3
我因为我的数据传输对象以递归方式相互引用而出现了这个错误。
例如:
客户 -> (拥有) -> 评级 评级 -> (属于) -> 客户
因此,您需要消除循环。
[DataContract]
public class Rating
{
    private Customer _customer;
    //[DataMember] // <-  EITHER HERE 
    public Customer Customer
    {
        get { return _customer; }
        set { _customer = value; }
    }
}


[DataContract]
public class Customer
{
    private long _customerID;
    [DataMember]
    public long CustomerID
    {
        get { return _customerID; }
        set { _customerID = value; }
    }

    [DataMember] // <- OR HERE
    public Rating Rating
    {
        get { return _rating; }
        set { _rating = value; }
    }
}

谢谢,你的解决方案帮了我很大的忙。 - user1429899

2

我添加了另一个字段,但没有在属性上设置set方法。 这是我解决同样错误的方法。

[DataMember]
public bool HasValue
{
    get { return true; }
    set { }//adding this line made the solution.
}

1

0
对于使用 EF 的 WCF,只需在上下文类中添加以下代码。
base.Configuration.ProxyCreationEnabled = false;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接