使用svcTraceViewer来调试WCF异常

来源:互联网 发布:python 打印字符串截取 编辑:程序博客网 时间:2024/04/30 07:24

我们在使用WCF开发应用系统的时候,经常会遇到一些连接错误。这个时候,其实我们可以让WCF记录日志,然后我们用svcTraceViewer工具可以分析这些日志然后找到问题。在这里,我将给大家演示一个实例。

首先我们创建一个WCF服务,这里是服务端代码

 

  1.     [ServiceContract]
  2.     public interface IService1
  3.     {
  4.         [OperationContract]
  5.         string GetData(int value);
  6.         [OperationContract]
  7.         List<CompositeType> GetDataUsingDataContract(CompositeType composite);
  8.         // TODO: Add your service operations here
  9.     }
  10.     // Use a data contract as illustrated in the sample below to add composite types to service operations
  11.     [DataContract]
  12.     public class CompositeType
  13.     {
  14.         bool boolValue = true;
  15.         string stringValue = "Hello ";
  16.         [DataMember]
  17.         public bool BoolValue
  18.         {
  19.             get { return boolValue; }
  20.             set { boolValue = value; }
  21.         }
  22.         [DataMember]
  23.         public string StringValue
  24.         {
  25.             get { return stringValue; }
  26.             set { stringValue = value; }
  27.         }
  28.     }
  29.     
  30.     public class Service1 : IService1
  31.     {
  32.         public string GetData(int value)
  33.         {
  34.             return string.Format("You entered: {0}", value);
  35.         }
  36.         public List<CompositeType> GetDataUsingDataContract(CompositeType composite)
  37.         {
  38.             List<CompositeType> composites = new List<CompositeType>();
  39.             for(int i=0;i<10;i++)
  40.             {
  41.                 CompositeType comp = new CompositeType();
  42.                 comp.BoolValue = composite.BoolValue;
  43.                 comp.StringValue = composite.StringValue + i.ToString();
  44.                 composites.Add(comp);
  45.             }
  46.             return composites;
  47.         }
  48.     }

然后我们添加一个控制台程序,添加一个服务引用,然后添加下面的代码

 

 

  1.     class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             Service1Client client = new Service1Client();
  6.             CompositeType ctype = new CompositeType();
  7.             ctype.BoolValue = true;
  8.             ctype.StringValue = "Justin ";
  9.             CompositeType[] composites = client.GetDataUsingDataContract(ctype);
  10.             foreach (CompositeType cType in composites)
  11.             {
  12.                 Console.WriteLine(cType.StringValue);
  13.             }
  14.             Console.ReadLine();
  15.         }
  16.     }

我们运行程序,就可以得到这样的输出:

Justin 0
Justin 1
Justin 2
Justin 3
Justin 4
Justin 5
Justin 6
Justin 7
Justin 8
Justin 9

 

这时候,我们可以把这个循环放大一些

 

  1.             for(int i=0;i<1000;i++)
  2.             {
  3.                 CompositeType comp = new CompositeType();
  4.                 comp.BoolValue = composite.BoolValue;
  5.                 comp.StringValue = composite.StringValue + i.ToString();
  6.                 composites.Add(comp);
  7.             }

再运行程序,我们可以看到这样的异常:

System.ServiceModel.CommunicationException: {"The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element."}

 

 这个异常提供的信息很全,我们可以修改一下配置文件,把MaxReceivedMessageSize设置成大一些的值。

[svcConfigEditor]

 

(*服务端和客户端两边都需要修改)

这样再运行一下,就可以看到结果了.

Justin 0
Justin 1
Justin 2
Justin 3
Justin 4
Justin 5

...
Justin 998
Justin 999

 

你可能奇怪,这里没有用到svcTraceViewer啊。不要紧,让我们把循环加到10000。

又出问题了,这次的异常内容是这样的:

{"An error occurred while receiving the HTTP response to http://localhost:8731/Design_Time_Addresses/MySampleService/Service1/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details."}

 

好像没有太多信息啊。不过异常里面提到了log,我们就来记录一些日志。svcConfigEditor可以方便的设置日志。

 

添加完日志我们再运行一下程序,错误照旧,停止debug, 我们用TraceViewer打开一下日志看看。

这时候我们可以看到在服务端有2个异常,,我们选择其中一个,

 

这时候我们可以看到,这里有非常详细的异常:

There was an error while trying to serialize parameter http://tempuri.org/:GetDataUsingDataContractResult. 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.

原来是序列化出现了问题,我们需要把MaxItemsInObjectGraph给修改一下。

我们需要为当前服务的ServiceBehavior添加一个DataContractSerializer, 把其中的MaxItemsInObjectGraph设置更大的值。(客户端也需要修改)。

 

重新运行程序,一切正常。

 

在WCF开发中,TraceViewer总可以给你意想不到的信息,实在是短小精悍的好工具。

原创粉丝点击