c# - SerializationException 不会转到 IErrorHandler

标签 c# .net wcf

在尝试反序列化一个相对较大的对象图时,我看到了奇怪的行为 ~10000 行,上面有 6 列。我确定问题是在尝试将此数组从服务反序列化回客户端时出现序列化异常。它适用于少于 9000 个对象的数据集,并且控制台窗口显示第一次机会 SerializationException,然后是 CommunicationException。我在控制台应用程序中自行托管此服务,因为我正在使用它与第三方 api 集成。我的第一个问题是有没有人知道是什么导致了这个序列化异常?

我在客户端和服务器上都按照以下方式在代码中配置绑定(bind),我想我已经把它调到最大可能了。

public static NetTcpBinding CreateStandardNetTcpBinding()
    {
        NetTcpBinding b = new NetTcpBinding(SecurityMode.None);
        b.OpenTimeout = new TimeSpan(0, 5, 0);
        b.ReceiveTimeout = new TimeSpan(0, 5, 0);
        b.SendTimeout = new TimeSpan(0, 5, 0);

        b.MaxReceivedMessageSize = Int32.MaxValue;
        b.MaxBufferSize =(int) b.MaxReceivedMessageSize;
        b.MaxBufferPoolSize = (int) b.MaxReceivedMessageSize;
        b.TransferMode= TransferMode.Buffered;



        b.ReaderQuotas.MaxNameTableCharCount = Int32.MaxValue;
        b.ReaderQuotas.MaxArrayLength = Int32.MaxValue;
        b.ReaderQuotas.MaxBytesPerRead = 4096;
        b.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
        b.ReaderQuotas.MaxDepth = 32;
        return b;
    }

我的第二个问题是为什么这个异常没有引发 IErrorHandler 接口(interface)上的 ProvideFault 方法。当我从 ServiceOperation 中引发异常时,ProvideFault 方法确实被引发了。 WCF 框架异常不是也被 IErrorHandler 捕获了吗?但是对于这个特殊问题,WCF 似乎在捕获序列化异常后突然/立即关闭 channel (因此超时是不可能的)。

A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll A first chance exception of type 'System.ServiceModel.CommunicationException' occurred in System.ServiceModel.dll

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:04:59.8939894'.

我的第三个问题是有人知道如何以编程方式添加 WCF 跟踪监听器吗?我在应用程序没有专用 app.config 文件的插件环境中工作。

谢谢!

---编辑---

是的,这就是问题所在。默认值约为 64K,我正在点击。一个解决方案是

在servicebehavior属性中设置MaxItemsInObjectGraph值 [ServiceBehavior(IncludeExceptionDetailInFaults = true, MaxItemsInObjectGraph = int.MaxValue)]

然后像这样在客户端上设置客户端的大小...

var behaviors = Endpoint.Contract.Operations
                                .Select(o => o.Behaviors.Find<DataContractSerializerOperationBehavior>())
                                .Where(behavior => behavior != null);
        foreach (var serializationBehavior in behaviors)
        {
            serializationBehavior.MaxItemsInObjectGraph = int.MaxValue;
        }

最佳答案

不是 100% 确定,但我会在这里尝试一些答案。

您可能会遇到 MaxItemsInObjectGraph DataContractSerializer 的属性。但是,根据 MSDN,默认值为 Int32.MaxValue (2,147,483,647),因此如果您没有触及该值,我认为情况并非如此。

另一个选择可能是增加 MaxDepth 配额,但我的钱会放在这个之前的 MaxItemsInObjectGraph 上。

您如何将创建的绑定(bind)分配给服务和客户端? MSDN 建议将此代码用于服务端:

OperationDescription operation = host.Description.Endpoints[0].Contract.Operations.Find("MyOperationName");
operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = 3;

不确定它如何应用于客户端(无需深入研究)。

对于第二个问题,MSDN有点不清楚,但似乎 IErrorHandler 可能无法处理序列化错误:

在调用所有 ProvideFault 实现并将响应消息传递给 channel 后,可能会发生异常。如果发生 channel 异常(例如,难以序列化消息),则会通知 IErrorHandler 对象。在这种情况下,您仍然应该确保您的开发环境捕获并向您显示此类异常,或者使用跟踪来发现问题。有关跟踪的更多信息,请参阅使用跟踪对您的应用程序进行故障排除。

对于您的最后一个问题,以编程方式启用 WCF 跟踪似乎是可能的,但有点令人费解:How do you enable wcf tracing without using a config file (programmatically)?

不确定这是否能解决您的问题,但希望它能为您提供一些可供探索的选择。

关于c# - SerializationException 不会转到 IErrorHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20863496/

相关文章:

c# - 从 If 语句内部调用组件

c# - 参数化 LINQ GroupBy

wcf - 具有字符串返回值(或参数)的 ASMX WebService 强制在 WCF 客户端中生成消息协定

.net - 如何加速 WCF “unit” 测试? (创建/关闭 ServiceHost 很慢...)

c# - 在本地和云上配置 Azure 共享缓存

c# - 从 32 位应用程序通过 COM 调用 x64 程序集

c# - 使用 C# 将 HTML 转换为图像。 Html 有标签以及 base64 字符串问题

asp.net - IIS Express 似乎没有发现对 applicationhost.config 的更改

c# - 正则表达式匹配不匹配的内容

c# - WCF 中的异步操作