你的位置:首页 > ASP.net教程

[ASP.net教程]WCF客户端配置以及代理


写在最前面:转载请注明出处

目录置顶:

  • 关于项目--------------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(1)
  • 架构搭建--------------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(2)
  • WCF服务端具体实现---------基于DDD领域驱动设计的WCF+EF+WPF分层框架(3)
  • WCF客户端配置以及代理-----基于DDD领域驱动设计的WCF+EF+WPF分层框架(4)
  • Domain具体实现------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(5)
  • WPF的UI层-----------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(6)
  • 组织架构--------------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(7)
  • 即时通讯--------------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(8)
  • 我的网站

前两天出差,所以这一系列的博客写到3就耽误了几天。今天回来了,接着写。

WCF客户端配置以及代理


 这一部分需要讲的内容不多,因为我没有使用引用服务来添加WCF服务,所以App.Config里面也没有自动生成配置信息以及Binding和Endpoint。如果需要引用的WCF服务很多的话,这个App.config看起来就很庞大,看着很不舒服。所以我在ACS.OA.Base项目中添加了一个帮助类(架构搭建--------------------基于DDD领域驱动设计的WCF+EF+WPF分层框架(2) 中也有简单介绍)WCFHandler 类,下面是代码:

 1   /// <summary> 2   /// 艾克仕网络云OA WCF配置 3   /// </summary> 4   public class WCFHandler 5   { 6     public static T CreateHttpServiceClient<T>(string webAddress, string serviceName) 7     { 8       T t = default(T); 9       object obj = Activator.CreateInstance(typeof(T), new object[] 10       { 11         GetHttpBinding(), 12         GetEndpoint(webAddress, serviceName) 13       }); 14       t = (T)(obj); 15       return t; 16     } 17  18     public static T CreateTcpServiceClient<T>(string webAddress, string serviceName, bool isStream=false) 19     { 20       T t = default(T); 21       object obj; 22       if (isStream) //流传输 23       { 24         obj = Activator.CreateInstance(typeof(T), new object[] 25         { 26           GetFileTcpBinding(), 27           GetEndpoint(webAddress, serviceName) 28         }); 29       } 30       else     //缓存传输 31       { 32         obj = Activator.CreateInstance(typeof(T), new object[] 33         { 34           GetTcpBinding(), 35           GetEndpoint(webAddress, serviceName) 36         }); 37       } 38       t = (T)(obj); 39       return t; 40     } 41      42  43     public static NetTcpBinding GetTcpBinding() 44     { 45       return new NetTcpBinding 46       { 47         MaxBufferPoolSize = 2147483646L, 48         MaxReceivedMessageSize = 2147483646L, 49         CloseTimeout = new TimeSpan(0, 0, 10), 50         OpenTimeout = new TimeSpan(0, 0, 10), 51         ReceiveTimeout = TimeSpan.MaxValue, 52         SendTimeout = new TimeSpan(0, 20, 0), 53         ReaderQuotas = 54         { 55           MaxDepth=64, 56           MaxStringContentLength=2147483646, 57           MaxArrayLength=2147483646, 58           MaxBytesPerRead=2147483646, 59           MaxNameTableCharCount=2147483646 60         }, 61         ReliableSession = 62         { 63           Enabled = true, 64           Ordered = true, 65           InactivityTimeout = new TimeSpan(0, 0, 10) 66         }, 67         Security = 68         { 69           Mode=SecurityMode.None, 70           Message = 71           { 72             ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows 73           }, 74           Transport = 75           { 76             ClientCredentialType = TcpClientCredentialType.Windows 77           } 78         }, 79  80       }; 81     } 82  83     /// <summary> 84     /// TCP大文件断点续传 85     /// </summary> 86     /// <returns></returns> 87     public static NetTcpBinding GetFileTcpBinding() 88     { 89       return new NetTcpBinding 90       { 91         MaxBufferPoolSize = 2147483646L, 92         MaxReceivedMessageSize = 2147483646L, 93         CloseTimeout = new TimeSpan(0, 0, 10), 94         OpenTimeout = new TimeSpan(0, 0, 10), 95         ReceiveTimeout = TimeSpan.MaxValue, 96         SendTimeout = new TimeSpan(0, 20, 0), 97         TransferMode=TransferMode.Streamed, 98         ReaderQuotas = 99         {100           MaxDepth=64,101           MaxStringContentLength=2147483646,102           MaxArrayLength=2147483646,103           MaxBytesPerRead=2147483646,104           MaxNameTableCharCount=2147483646105         },106         //ReliableSession =107         //{108         //  Enabled = true,109         //  Ordered = true,110         //  InactivityTimeout = new TimeSpan(1, 0, 0)111         //},112         //Security =113         //{114         //  Mode=SecurityMode.None,115         //  Message =116         //  {117         //    ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows118         //  },119         //  Transport =120         //  {121         //    ClientCredentialType = TcpClientCredentialType.Windows122         //  }123         //},124 125       };126     }127 128     public static WSHttpBinding GetHttpBinding()129     {130       return new WSHttpBinding131       {132         MaxBufferPoolSize = 2147483646L,133         MaxReceivedMessageSize = 2147483646L,134         CloseTimeout = new TimeSpan(0, 0, 10),135         OpenTimeout = new TimeSpan(0, 0, 10),136         ReceiveTimeout = new TimeSpan(0, 20, 0),137         SendTimeout = new TimeSpan(0, 20, 0),138         ReliableSession =139         {140           Enabled = true,141           Ordered = true,142           InactivityTimeout = new TimeSpan(0, 0, 10)143         },144         UseDefaultWebProxy = false,145         Security =146         {147           Mode = SecurityMode.None,148           Message =149           {150             ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows151           },152           Transport =153           {154             ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows155           }156         },157       };158     }159     public static EndpointAddress GetEndpoint(string webAddress, string serviceName)160     {161       Uri uri = new Uri(webAddress + "/" + serviceName + ".svc");162       return new EndpointAddress(uri, new AddressHeader[0]);163     }164 165     public static EndpointAddress GetIMEndpoint(string webAddress, string serviceName)166     {167       Uri uri = new Uri(webAddress + "/" + serviceName + ".svc");168       return new EndpointAddress(uri, new AddressHeader[0]);169     }170   }

WCFHandler View Code

我的WPF客户端使用的是NET.TCP,Web端使用的是WSHTTP,所以两个配置信息都有,大家可以做一个参考。

我再把客户端的App.config配置文件部分代码贴出来

1 <appSettings>2   <add key="HTTPAddress" value="http://10.32.100.251/ACS.OA.Test;http://10.32.100.251/ACS.OA.Test;http://lineoa.shijian365.cn/ACS.OA" />3   <add key="WCFAddress" value="net.tcp://localhost/DDD/ACS.CloudOA.WCFService;net.tcp://10.32.100.251/ACS.OA.Test;net.tcp://oa.acssoft.cn/CloudOA" />4   <add key="ACS_WebTCPAddress" value="net.tcp://localhost/DDD/ACS_WEB/ACS.WCFService;net.tcp://10.32.100.251/ACS.OA.Test;net.tcp://oa.acssoft.cn/Web" />5   <!--部署环境 0:开发;1:测试;2:正式-->6   <add key="DeployType" value="2" />7  </appSettings>

这里我讲一下我的用法:(也希望大家说说你们是如何处理这个事情的,大家可以相互讨论一下)

一般我们项目开发都需要经历 开发、内部测试、正式部署 三个阶段 我在config中只需要修改 DeployType 的值就可以将项目修改为 开发、内部测试、正式部署 阶段,之后生成项目打包就OK了,是不是很方便???

其实大家可以看到我在 HTTPAddress WCFAddress ACS_WebTCPAddress 三个的value值都用【 ;】分割为三部分,然后我会在ACS.OA.Golbal项目中SystemConfig.cs文件中获取这里的值,代码如下:

 1 public static int DeployType = StringHelper.ToInteger(ConfigHelper.GetAppSettingsValue("DeployType")); 2  3  4     private static string _wcfaddress = ConfigHelper.GetAppSettingsValue("WCFAddress"); 5     /// <summary> 6     /// 艾克仕网络ACS.CloudOA NET.TCP地址 7     /// </summary> 8     public static string WCFAddress 9     {10       get11       {12         string address = "";13         if (string.IsNullOrEmpty(_wcfaddress) || !_wcfaddress.Contains(";"))14         {15           return address;16         }17         string[] wcfarr = _wcfaddress.Split(';');18         address = wcfarr.Length > DeployType ? wcfarr[StringHelper.ToInteger(DeployType)] : "";19         return address;20       }21     }22 23     private static string _httpAddress = ConfigHelper.GetAppSettingsValue("HTTPAddress");24     /// <summary>25     /// 艾克仕网络ACS.CloudOA HTTP地址26     /// </summary>27     public static string HTTPAddress28     {29       get30       {31         string address = "";32         if(string.IsNullOrEmpty(_httpAddress) || !_httpAddress.Contains(";"))33         {34           return address;35         }36         string[] httparr = _httpAddress.Split(';');37         address = httparr.Length > DeployType ? httparr[StringHelper.ToInteger(DeployType)] : "";38         return address;39       }40     }41 42     private static string _ACS_WebTCPAddress = ConfigHelper.GetAppSettingsValue("ACS_WebTCPAddress");43     /// <summary>44     /// 艾克仕网络ACS.Web服务NET.TCP地址45     /// </summary>46     public static string ACS_WebTCPAddress47     {48       get49       {50         string address = "";51         if (string.IsNullOrEmpty(_ACS_WebTCPAddress) || !_ACS_WebTCPAddress.Contains(";"))52         {53           return address;54         }55         string[] wcfarr = _ACS_WebTCPAddress.Split(';');56         address = wcfarr.Length > DeployType ? wcfarr[StringHelper.ToInteger(DeployType)] : "";57         return address;58       }59     }

这样值就拿到了,这样做的话就不用每次老板催着要发包测试或者发布新版本的时候手忙脚乱的了。当然我不建议在每次用的时候直接调用,我建议在客户端本地缓存中保存一下,再使用缓存,要不然每次调用都需要去读一下config。搭建架构,只要能想到可以优化就要毫不犹豫的去优化,尽管这个地方对整体性能影响很小。

WCF客户端配置就写这些了。下面我再简单讲一下WCF代理类:

WCF代理类


 代理类我是单独建了一个项目ACS.OA.WCFClient,然后每一个需要引用WCF代理类的项目我都会在ACS.OA.WCFClient项目中建立一个文件夹,例如我这里三个项目用到这个代理,ACS.OA.WCFClient项目中就有三个项目对应的文件夹

代理类使用SvcUtil生成,我在这里贴一个代理实例:

 1   [System.Diagnostics.DebuggerStepThroughAttribute()] 2   [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] 3   public partial class SettingServiceClient : System.ServiceModel.ClientBase<ISettingService>, ISettingService 4   { 5  6     public SettingServiceClient() 7     { 8     } 9 10     public SettingServiceClient(string endpointConfigurationName) :11         base(endpointConfigurationName)12     {13     }14 15     public SettingServiceClient(string endpointConfigurationName, string remoteAddress) :16         base(endpointConfigurationName, remoteAddress)17     {18     }19 20     public SettingServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :21         base(endpointConfigurationName, remoteAddress)22     {23     }24 25     public SettingServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :26         base(binding, remoteAddress)27     {28     }29 30     #region 艾克仕网络ACS.CloudOA企业名片31     32     /// <summary>33     /// 企业名片34     /// </summary>35     public byte[] GetFirmCard(byte[] bytData)36     {37       return base.Channel.GetFirmCard(bytData);38     }39 40     /// <summary>41     /// 保存企业信息42     /// </summary>43     public byte[] AddFirmCard(byte[] bytData)44     {45       return base.Channel.AddFirmCard(bytData);46     }47 48     /// <summary>49     /// 保存企业认证信息50     /// </summary>51     public byte[] AddFirmCardCertified(byte[] bytData)52     {53       return base.Channel.AddFirmCardCertified(bytData);54     }55     #endregion56   }

SettingService View Code

 WCF客户端配置和代理类就这些了,至于如何使用我在后面的实例部分会讲到。