WCF dataContractSerializer設置技巧講解
大家可能知道,WCF這樣一款功能強大的開發插件,其中有很多內容值得我們去深入的探討研究。在這篇文章中,我們將會針對其中一個比較重要的屬性,WCF dataContractSerializer的相關設置進行一個詳細的介紹。#t#
在WCF的使用過程中,有時會碰到傳遞的數據量比較巨大,客戶端程序報錯。常見的解決方法就是通過增大改變服務端與客戶端配置文件serviceBehaviors的dataContractSerializer 的maxItemsInObjectGraph屬性。有沒有不通過配置文件,直接硬編碼增大maxItemsInObjectGraph的值呢(此文不是考慮那種做法的優劣,而僅僅是探討一種可能)?答案是肯定的。方法如下。
既然wcf的maxItemsInObjectGraph可以通過配置去設定,那么應該也有可能通過代碼去設定。因為maxItemsInObjectGraph 通過配置文件信息的讀取到這個信息后,最終應該把讀到的信息去設置某個類的屬性,從而改變服務的配置。
1. 先從有配置文件時,服務的運行開始著手。服務端配置文件如下
- < behaviors>
- < serviceBehaviors>
- < behavior name="Service1Behavior">
- < serviceMetadata httpGetEnabled="true" />
- < serviceDebug includeExceptionDetailInFaults="true" />
- < dataContractSerializer maxItemsInObjectGraph="2147483647" />
- < /behavior>
- < /serviceBehaviors>
- < /behaviors>
- < /system.serviceModel>
在ServiceHost實例化完成后加入如下的代碼:
- public void Start()
- {
- ServiceHost host = new ServiceHost(typeof(Service1));
- Console.WriteLine("---------------------------------");
- foreach (var item in host.Description.Behaviors)
- {
- Console.WriteLine(item.ToString());
- }
- Console.WriteLine("---------------------------------");
- host.Open();
- }
在輸出窗口得到以下信息:
---------------------------------
System.ServiceModel.ServiceBehaviorAttribute
Microsoft.VisualStudio.Diagnostics.ServiceModelSink.Behavior
System.ServiceModel.Description.ServiceMetadataBehavior
System.ServiceModel.Description.ServiceDebugBehavior
System.ServiceModel.Dispatcher.DataContractSerializerServiceBehavior
System.ServiceModel.Description.ServiceAuthorizationBehavior
進一步跟蹤得知。WCF dataContractSerializer對應的類就是DataContractSerializerServiceBehavior。
2. 構造DataContractSerializerServiceBehavior實例,設置maxItemsInGraph屬性,并把實例插入host.Description.Behaviors中。
用reflector 查看DataContractSerializerServiceBehavior,發現聲明如下
internal class DataContractSerializerServiceBehavior£ºIServiceBehavior, IEndpointBehavior{}看來只能用反射類實例化它了。具體代碼如下:
- ServiceHost host = new ServiceHost(typeof(Service1));
- Type t = host.GetType();
- object obj= t.Assembly.CreateInstance("System.ServiceModel.
Dispatcher.DataContractSerializerServiceBehavior",true,
BindingFlags.CreateInstance|BindingFlags.Instance|
BindingFlags.NonPublic ,null,new object[]{false ,Int32.MaxValue },
null,null);- IServiceBehavior myServiceBehavior=obj as IServiceBehavior ;
- if (myServiceBehavior != null)
- {
- host.Description.Behaviors.Add(myServiceBehavior);
- }
- Console.WriteLine("---------------------------------");
- foreach (var item in host.Description.Behaviors)
- {
- Console.WriteLine(item.ToString());
- }
- Console.WriteLine("---------------------------------");
- host.Open();3. 然后注釋掉配置文件的dataContractSerializer
- < behaviors>
- < serviceBehaviors>
- < behavior name="Service1Behavior">
- < serviceMetadata httpGetEnabled="true" />
- < serviceDebug includeExceptionDetailInFaults="true" />
- < !--< dataContractSerializer maxItemsInObjectGraph="2147483647" />-->
- < /behavior>
- < /serviceBehaviors>
- < /behaviors>
4. 經測試,硬編碼設置maxItemsInObjectGraph,與WCF dataContractSerializer設置配置文件的屬性能達到同樣的效果