zoukankan      html  css  js  c++  java
  • WCF序列化65536大小限制的问题

    在Silverlight+WCF RIA Service或者WCF Service的架构中,经常会遇到WCF序列化65536大小限制的问题。由于WCF RIA Service没有提供明确的异常信息和错误信息,所以往往构成误导。

    WCF RIA Service没有提供准确的异常信息和错误原因

    比如我就遇到Silverlight客户端调用WCF RIA Service失败,异常信息是:System.ServiceModel.DomainServices.Client.DomainOperationException: Load operation failed for query 'GetProducts'. Inner exception message: Timeout expired.,居然异常信息是超时TimeOut,难道调用WCF RIA Service需要这么多时间吗?

    换了一个数据库和机器,还是Silverlight客户端调用WCF RIA Service失败,异常信息变为:System.ServiceModel.DomainServices.Client.DomainOperationException: Load operation failed for query 'GetProducts'. The remote server returned an error: NotFound. ---> System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. 异常信息又变成了Server Not Found。

    事实上,当客户端调用WCF服务的时候比如调用WCF 服务的*.svc地址时候比如http://localhost:8562/ClientBin/MyNameSpace-DomainServices-MyDomainService.svc/binary/GetProducts?model=&productCode=&type=mp,如果服务端*.svc发生了任何状况不能给出200的应答码,就会返回一个错误比如404,而*.svc没有这个404重定向,就给个Server NotFound的异常信息,真是令人崩溃。

    打开诊断选项找到WCF内部异常原因

    其实如果需要查看Domain Service和Client的异常信息,可以在Web.config打开诊断选项并且用WCF服务跟踪查看器(SvcTraceViewer.exe)查看错误日志:

       1: <configuration>
       2:  <system.diagnostics>
       3:     <sources>
       4:       <source name="System.ServiceModel" switchValue="Information, ActivityTracing"
       5:               propagateActivity="true">
       6:         <listeners>
       7:           <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener"
       8:               initializeData= "C:\WCFLogs\Traces.svclog" />
       9:         </listeners>
      10:       </source>
      11:     </sources>
      12:   </system.diagnostics>
      13: </configuration>

    使用WCF Sevice Trace Viewer定位异常

    我用WCF服务跟踪查看器(SvcTraceViewer.exe)查看了错误日志,发现不是Server Not Found错误,而是WCF序列化65536大小限制,错误信息是:There was an error while trying to serialize parameterhttp://tempuri.org/:GetProductsResult. The InnerException message was 'Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota. '.  Please see InnerException for more details.,下面是截图:

    debug_HttpWatch2

    Stacktrace:

    System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph) 
    System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph) 
    System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest) 
    System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest) 
    System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer) 
    System.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter writer) 
    System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer) 
    System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer) 
    System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer) 
    System.ServiceModel.DomainServices.Hosting.PoxBinaryMessageEncodingBindingElement.PoxBinaryMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset) 
    System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message) 
    System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout) 
    System.ServiceModel.Channels.HttpRequestContext.OnReply(Message message, TimeSpan timeout) 
    System.ServiceModel.Activation.HostedHttpContext.OnReply(Message message, TimeSpan timeout) 
    System.ServiceModel.Channels.RequestContextBase.Reply(Message message, TimeSpan timeout) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage9(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage8(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc) 
    System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) 
    System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext) 
    System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext) 
    System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result) 
    System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result) 
    System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) 
    System.ServiceModel.Diagnostics.TraceUtility.&lt;&gt;c__DisplayClass4.&lt;CallbackGenerator&gt;b__2(AsyncCallback callback, IAsyncResult result) 
    System.Runtime.AsyncResult.Complete(Boolean completedSynchronously) 
    System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item) 
    System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread) 
    System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread) 
    System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread) 
    System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback) 
    System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result) 
    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest() 
    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest() 
    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state) 
    System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state) 
    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state) 
    System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) 
    System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) 
    System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

     

    解决办法

    既然问题已经明确是WCF序列化和反序列化的65536大小限制导致Silverlight客户端接收不到,那就调整这个参数,异常信息已经给出提示可以配置MaxItemsInObjectGraph这个参数。我们修改Web.config即可:

       1: <configuration>
       2:   <system.serviceModel>
       3:     
       4:     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
       5:         multipleSiteBindingsEnabled="true" />
       6:     
       7:     <!--设置 maxItemsInObjectGraph -->
       8:     <services>
       9:  
      10:       <!--注意下面这个name属性,必须改成你自己的namespace+DomainService类名!! -->
      11:       <service name="MyNamespace.MyDomainServiceClass" 
      12:                behaviorConfiguration="MyWCFConfig" />
      13:     </services>
      14:     <behaviors>
      15:       <serviceBehaviors>
      16:         <behavior name="MyWCFConfig">
      17:           <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      18:         </behavior>
      19:       </serviceBehaviors>
      20:     </behaviors>
      21:     
      22:   </system.serviceModel>
      23: </configuration>

    上面是最简单的配置方法,当然你的WCF如果很复杂,建议配置binding, endpoint等等,关于WCF配置Web.config,参考这个这个。在SilverlightChina上专家MVP有这个帖子解决同样问题的,我使用下来不管用,而且没说明怎么调试问题。

    Powered By D&J (URL:http://www.cnblogs.com/Areas/)
  • 相关阅读:
    如何利用python制作微信好友头像照片墙?
    机器学习入门路线和资源
    突然“被辞职”的时候,原来可以拿到这么多钱!
    一个致命的 Redis 命令,导致公司损失 400 万
    程序员:想知道你每天按了多少次键盘吗?
    想了解真实的中国历史吗?建议看看这10部历史纪录片,受益终生!
    SpringBlade 2.0-RC3 发布,全新的微服务开发平台
    Syncd-开源自动化部署工具
    学习Spring Boot看这两个开源项目就够了!非得值得收藏的资源
    大型视频直播平台架构由浅入深详细讲解
  • 原文地址:https://www.cnblogs.com/Areas/p/2186610.html
Copyright © 2011-2022 走看看