【问题标题】:WCF can return single object just fine but fails when returning a listWCF 可以很好地返回单个对象,但返回列表时失败
【发布时间】:2013-03-21 17:37:03
【问题描述】:

我已经通过列表通过我的 WCF 服务发送了各种其他对象,没有任何问题,但是当我尝试发送这个特定对象(在列表中)时,我得到了一种超时错误。

跟踪标识符是: TraceIdentifierhttp://msdn.microsoft.com/da-DK/library/System.ServiceModel.Diagnostics.TraceTruncatedQuotaExceeded.aspx

奇怪的是:我有另一种方法专门返回对象(不在列表中),它工作正常。

此外,在调试时,我发现该方法(在服务端)返回列表很好,但是客户端显然无法接收它。

这是调用服务的方法(它在声明“revs”的那一行失败):

public void GetReviewsInModule()
        {
            using (var db = new RentItServiceClient())
            {
                var revs = db.GetReviewsInModule(1);
            }
        }

以下是实际将对象作为列表返回的方法(调试它并返回它正常):

public List<ReviewModule> GetReviewsInModule(int id)
    {
        using (Context con = new Context())
        {
            con.Configuration.ProxyCreationEnabled = false;
            var mod = con.Modules.Find(id);
            if (mod == null)
                throw new WebServiceValidationException("Object does not exist");
            List<ReviewModule> revs = con.ModuleReviews.Include("User").Where(r => r.Module.Id == id).ToList();
            return revs;
        }
    }

此外,列表中的对象几乎没有任何大小,所以请不要告诉我提高发送/接收限制/超时。

【问题讨论】:

  • 我很久以前就放弃了 SOAP,转而使用 REST,只是移动了一个 json 对象 - 使用 SOAP 服务是否有特定原因?此外,检查 WSDL 以查看其中是否有对象,或者至少有一个链接 - 您正在寻找一个 xsd,因为 SOAP 使用 XML
  • 该链接指向 msdn 的丹麦突变并且不起作用。

标签: c# .net wcf web-services web


【解决方案1】:

仅根据您发布的代码很难给您答案,因为仅从那几个 sn-ps 中复制问题是不可能的。 (为此,您需要发布 ReviewModule 的完整定义、您的服务合同等)。

因此这只是一个猜测,但是当我在端点中使用 Using 块时,我在使用 WCF 和 MVC Web Api 设置 RESTful Web 服务时被抓了几次。尽管 Using 是 C# 中的一个有价值的构造,但我发现,当您在表示最终由您无法控制的代码调用的端点的方法中定义了一个时,Using 块依赖的 IDisposable 接口工作得到弄乱。也就是说,您在您的方法中定义了一个对象(在本例中是一个名为“con”的 Context 类型的对象),只是稍后您所依赖的 WCF 框架才会尝试访问在您的端点中创建的对象.当 WCF 框架完成其工作时,您的 Context 对象上的 Dispose() 方法可能已经被您的代码调用,这意味着 WCF 框架无法以它需要的方式访问它以便能够返回您的服务打算提供的数据。即使当您从完全受您控制的代码中对其进行单元测试时,即使您的方法是独立工作的,情况也可能如此。

要查看这是否是您的问题,请尝试删除“GetReviewsInModule”方法/服务端点中的 Using 块,如下所示:

public List<ReviewModule> GetReviewsInModule(int id)
{
    Context con = new Context();
    con.Configuration.ProxyCreationEnabled = false;
    var mod = con.Modules.Find(id);
    if (mod == null) throw new WebServiceValidationException("Object does not exist");
    List<ReviewModule> revs = con.ModuleReviews.Include("User").Where(r => r.Module.Id == id).ToList();
    return revs;
}

如果这导致您的端点按预期开始工作,您可以担心如何管理对象处置并避免将内存泄漏作为一个单独的问题。

【讨论】:

  • 嗯?创建列表,释放 Context 对象,将列表序列化并返回给客户端,应该是什么问题?
  • 我只是在说我所看到的,并在面对不允许读者复制问题的模棱两可的问题描述时提出问题的可能原因。 WCF 和 MVC Web Api 框架有时无法访问在用户定义代码中使用块中定义的对象。这两个框架都没有报告问题所在。
  • 我知道你在做什么,我只是在问这是否有意义。 using 块只不过是在执行离开块时在对象上调用 Dispose() 的简写。在这种情况下,由于 revs 对象在发生这种情况时被初始化,那么 Dispose() 调用如何导致超时?
  • PS:您提到的序列化仅在稍后发生,在 WCF 框架内。不在端点本身内。 WCF 框架需要能够访问由上述代码中的 revs 变量引用的 List 类型的对象,以便能够序列化结果。这就是我所看到的问题中似乎出现问题的地方。当/如果 OP 尝试建议的方法时,他会确定这是否是他的问题。
  • 我已经尝试了上面的代码,但它仍然给出了同样的错误。事实是该方法生成的列表很好,但是调用方法中没有正确接收到它。
【解决方案2】:

这实际上也取决于结果列表中有多少元素,而不仅仅是单个元素的大小。您可以使用一些配置元素:

maxReceivedMessageSize
maxBufferSize
maxBufferPoolSize
maxArrayLength
maxStringContentLength

另一个解决方案是切换到流式 WCF 服务。请注意,您不能混合使用流式操作和缓冲操作 - 我有时实际上会创建两个 WCF 服务,一个用于流式操作,一个用于缓冲操作。

【讨论】:

  • 好吧,即使列表中只有 1 个元素,它也会失败。此外,我们已经在使用流式 Wcf。
  • 不可能。否则,您的服务将不得不返回Stream,而不是List&lt;...&gt;,因为流式服务只能返回流并将流作为参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 2019-06-08
  • 1970-01-01
  • 2015-01-23
  • 2010-09-28
  • 2011-11-11
相关资源
最近更新 更多