【问题标题】:Underlying connection closed exception thrown in web service callWeb 服务调用中引发的基础连接关闭异常
【发布时间】:2014-06-13 08:43:20
【问题描述】:

我知道以前有人问过这个问题,并且提出了很多建议,但我都尝试了所有这些都没有奏效,所以我想看看是否有人对这个问题有额外的了解。

场景: 我有一个控制台应用程序,我在其中添加了对 ASMX Web 服务的 Web 引用。 在控制台应用程序中,我生成了一个这样的派生类:

public class OverridenWebRequestReporting : webservice.Reporting
{
    public OverridenWebRequestReporting(string addr)
        : base(addr)
    {
    }

    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
        System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
        webRequest.KeepAlive = false;
        webRequest.ProtocolVersion = HttpVersion.Version10;
        webRequest.ServicePoint.ConnectionLimit = 1;
        return webRequest;
    }
}

对web服务方法的调用如下:

        OverridenWebRequestReporting reportingService = new OverridenWebRequestReporting("http://some_web_location_where_the_service_is_deployed/Reporting.svc");

        CredentialCache cache = new CredentialCache();

        cache.Add(new Uri("http://some_web_location_where_the_service_is_deployed/Reporting.svc"), "NTLM",new NetworkCredential("username", "password", "domain"));

        reportingService.Credentials = cache;

        System.Net.ServicePointManager.Expect100Continue = false;

        DataTable dt = new DataTable();

        using (reportingService)
        {
            try
            {
                dt = reportingService.GetAllDocumentsMetadataFromSP("someString", "anotherString");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

        }

使用调试器,我可以清楚地看到调用,并且返回了一个有效的数据表,但是当最后一个return语句执行时,代码进入了catch块,出现“底层连接已关闭”的异常:预期保持活动状态的连接已被服务器关闭。”被扔了

框架是 4.5。

我还能做些什么来防止抛出异常?

【问题讨论】:

  • 有时当您尝试将服务添加为服务引用时,代码生成器会引发相同的异常,但会显示详细消息。我的猜测是,您的返回值中有一些内容无法序列化到客户端,或者您访问了在返回完成之前释放的惰性变量。
  • 控制台应用程序只是一个“测试环境”。这是一个古老的遗产。我可以简单地将其添加为服务参考。您认为这可能会对通话产生负面影响吗?
  • 我只有一个 asmx,它被添加为 Web 参考。原因(我花了一段时间才记住这一点:P)是我无法向我的应用添加对 System.ServiceModel 的引用。
  • 发送给客户端的所有内容都必须是可序列化的,因为客户端必须知道将数据重建为正确数据类型的规则。我不认为数据表是可序列化的。也许将结果作为连接字符串返回以测试是否不再抛出异常将使您走上正确的轨道。
  • DataTable 序列化就好了。不过,您必须遵守某些规则,例如在服务器端设置 TableName 属性(这个在过去让我印象最深)。

标签: c# asmx webservice-client


【解决方案1】:

解决方案是变化的组合:

1) 按照 Kirill 的建议,为数据表添加一个名称

2) 在服务中使用dt.WriteXml(writer, XmlWriteMode.WriteSchema, false);,生成一个XML字符串

3) 使用

using (StringReader r = new StringReader(XMLSerializedResult))
        {
            dt.ReadXml(XmlReader.Create(r));
        }

在客户端反序列化 XML 字符串。

谢谢大家的建议。

【讨论】:

    【解决方案2】:

    查看Closing WCF connection。基本上,当使用块调用 Dispose 时,就会发生这种情况。解决方案:跳过使用,根据需要调用 .Close 或 .Abort。

    MSDN 链接:http://msdn.microsoft.com/en-us/library/aa355056.aspx

    【讨论】:

    • 我已经尝试删除 using 块(实际上,它一开始并不存在)但它仍然命中了 catch 块。我刚刚添加了 using 块,希望这可以解决问题。不是这样的……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    相关资源
    最近更新 更多