Wcf调用方式
C#动态调用WCF接口,两种方式任你选。
写在前面
接触WCF还是它在最初诞生之处,一个分布式应用的巨作。 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项目时用到了WCF。 从这个小项目中我学会了两个地方: 1、利用IIS部署WCF服务,也就是大家接触到的发布SVC文件。2、动态调用WCF接口。
在这个项目中接触WCF时遇到的其实不仅仅是这两个问题,甚至连IIS支持SVC文件也让我折腾了好几把,IIS都重新卸载了两次。 我在这篇文章里用两种方式来实现。
如何使用
1、第一种方式比较简单,而且也是大家喜欢的,因为不需要任何配置文件就可解决,只需知道服务契约接口和服务地址就可以调用。
2、使用Invoke的方式,但是需要在调用客户端配置WCF,配置后在Invoke类里封装服务契约接口即可。
客户端调用DEMO
|
1
2
3
4
5
6
7
|
//第一种方式string url = "http://localhost:3000/DoubleService.svc";IDoubleService proxy = WcfInvokeFactory.CreateServiceByUrl<IDoubleService>(url);int result = proxy.Add(1, 3);//第二种方式<br><br>int result1 = WCFInvoke.Invoke(t => t.Add(1, 3));<br><br> |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="NewBehavior"> <dataContractSerializer maxItemsInObjectGraph="65536000" /> </behavior> </endpointBehaviors> </behaviors> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IDoubleService" closeTimeout="01:00:00" openTimeout="01:00:00" sendTimeout="01:00:00" receiveTimeout="01:00:00" maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"> <readerQuotas maxDepth="128" maxStringContentLength="2147483647" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> </binding> </basicHttpBinding> <netMsmqBinding> <binding name="NetMsmqBinding_IAsyncSender"> <security mode="None" /> </binding> </netMsmqBinding> </bindings> <client> <endpoint address="http://localhost:3000/DoubleService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDoubleService" contract="DoubleStone.WebHost.IDoubleService" name="BasicHttpBinding_IDoubleService" /> </client> </system.serviceModel> |
第一种调用方式
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
public class WcfInvokeFactory { #region WCF服务工厂 public static T CreateServiceByUrl<T>(string url) { return CreateServiceByUrl<T>(url, "basicHttpBinding"); } public static T CreateServiceByUrl<T>(string url, string bing) { try { if (string.IsNullOrEmpty(url)) throw new NotSupportedException("This url is not Null or Empty!"); EndpointAddress address = new EndpointAddress(url); Binding binding = CreateBinding(bing); ChannelFactory<T> factory = new ChannelFactory<T>(binding, address); return factory.CreateChannel(); } catch (Exception ex) { throw new Exception("创建服务工厂出现异常."); } } #endregion #region 创建传输协议 /// <summary> /// 创建传输协议 /// </summary> /// <param name="binding">传输协议名称</param> /// <returns></returns> private static Binding CreateBinding(string binding) { Binding bindinginstance = null; if (binding.ToLower() == "basichttpbinding") { BasicHttpBinding ws = new BasicHttpBinding(); ws.MaxBufferSize = 2147483647; ws.MaxBufferPoolSize = 2147483647; ws.MaxReceivedMessageSize = 2147483647; ws.ReaderQuotas.MaxStringContentLength = 2147483647; ws.CloseTimeout = new TimeSpan(0, 30, 0); ws.OpenTimeout = new TimeSpan(0, 30, 0); ws.ReceiveTimeout = new TimeSpan(0, 30, 0); ws.SendTimeout = new TimeSpan(0, 30, 0); bindinginstance = ws; } else if (binding.ToLower() == "nettcpbinding") { NetTcpBinding ws = new NetTcpBinding(); ws.MaxReceivedMessageSize = 65535000; ws.Security.Mode = SecurityMode.None; bindinginstance = ws; } else if (binding.ToLower() == "wshttpbinding") { WSHttpBinding ws = new WSHttpBinding(SecurityMode.None); ws.MaxReceivedMessageSize = 65535000; ws.Security.Message.ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows; ws.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows; bindinginstance = ws; } return bindinginstance; } #endregion } |
第二种调用方式
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class WCFInvoke { /// <summary> /// 你需要调用的服务契约 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="func"></param> /// <returns></returns> public static T Invoke<T>(Func<IDoubleService, T> func) { IServiceInvoker serviceInvoker=new WCFServiceInvoker(); return serviceInvoker.InvokeService(func); } } |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
public interface IServiceInvoker { void InvokeService<T>(Action<T> invokeHandler) where T : class; TReslt InvokeService<T, TReslt>(Func<T, TReslt> invokeHandler) where T : class; }public class WCFServiceInvoker:IServiceInvoker { private static readonly ChannelFactoryManager FactoryManager = new ChannelFactoryManager(); private static readonly ClientSection ClientSection = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection; public void InvokeService<T>(Action<T> invokeHandler) where T : class { KeyValuePair<string, string> endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T)); var arg = FactoryManager.CreateChannel<T>(endpointNameAddressPair.Key, endpointNameAddressPair.Value); var obj2 = (ICommunicationObject)arg; try { invokeHandler(arg); } finally { try { if (obj2.State != CommunicationState.Faulted) { obj2.Close(); } } catch { obj2.Abort(); } } } public TReslt InvokeService<T, TReslt>(Func<T, TReslt> invokeHandler) where T : class { KeyValuePair<string, string> endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T)); var arg = FactoryManager.CreateChannel<T>(endpointNameAddressPair.Key, endpointNameAddressPair.Value); var obj2 = (ICommunicationObject)arg; try { return invokeHandler(arg); } finally { try { if (obj2.State != CommunicationState.Closed || obj2.State != CommunicationState.Faulted) { obj2.Close(); } } catch { obj2.Abort(); } } } private KeyValuePair<string, string> GetEndpointNameAddressPair(Type serviceContractType) { var configException = new ConfigurationErrorsException( string.Format( "No client endpoint found for type {0}. Please add the section <client><endpoint name=\"myservice\" address=\"http://address/\" binding=\"basicHttpBinding\" contract=\"{0}\"/></client> in the config file.", serviceContractType)); if (((ClientSection == null) || (ClientSection.Endpoints == null)) || (ClientSection.Endpoints.Count < 1)) { throw configException; } foreach (ChannelEndpointElement element in ClientSection.Endpoints) { if (element.Contract == serviceContractType.ToString()) { return new KeyValuePair<string, string>(element.Name, element.Address.AbsoluteUri); } } throw configException; } } |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
public class ChannelFactoryManager : IDisposable { private static readonly Dictionary<Type, ChannelFactory> Factories = new Dictionary<Type, ChannelFactory>(); private static readonly object SyncRoot = new object(); public void Dispose() { Dispose(true); } public virtual T CreateChannel<T>() where T : class { return CreateChannel<T>("*", null); } public virtual T CreateChannel<T>(string endpointConfigurationName) where T : class { return CreateChannel<T>(endpointConfigurationName, null); } public virtual T CreateChannel<T>(string endpointConfigurationName, string endpointAddress) where T : class { T local = GetFactory<T>(endpointConfigurationName, endpointAddress).CreateChannel(); ((IClientChannel)local).Faulted += ChannelFaulted; return local; } protected virtual ChannelFactory<T> GetFactory<T>(string endpointConfigurationName, string endpointAddress) where T : class { lock (SyncRoot) { ChannelFactory factory; if (!Factories.TryGetValue(typeof(T), out factory)) { factory = CreateFactoryInstance<T>(endpointConfigurationName, endpointAddress); Factories.Add(typeof(T), factory); } return (factory as ChannelFactory<T>); } } private ChannelFactory CreateFactoryInstance<T>(string endpointConfigurationName, string endpointAddress) { ChannelFactory factory = null; factory = !string.IsNullOrEmpty(endpointAddress) ? new ChannelFactory<T>(endpointConfigurationName, new EndpointAddress(endpointAddress)) : new ChannelFactory<T>(endpointConfigurationName); factory.Faulted += FactoryFaulted; factory.Open(); return factory; } private void ChannelFaulted(object sender, EventArgs e) { var channel = (IClientChannel)sender; try { channel.Close(); } catch { channel.Abort(); } } private void FactoryFaulted(object sender, EventArgs args) { var factory = (ChannelFactory)sender; try { factory.Close(); } catch { factory.Abort(); } Type[] genericArguments = factory.GetType().GetGenericArguments(); if ((genericArguments.Length == 1)) { Type key = genericArguments[0]; if (Factories.ContainsKey(key)) { Factories.Remove(key); } } } protected virtual void Dispose(bool disposing) { if (disposing) { lock (SyncRoot) { foreach (Type type in Factories.Keys) { ChannelFactory factory = Factories[type]; try { factory.Close(); } catch { factory.Abort(); } } Factories.Clear(); } } } } |
参考:https://www.cnblogs.com/sword-successful/p/4760376.html
Wcf调用方式的更多相关文章
- Wcf:可配置的服务调用方式
添加wcf服务引用时,vs.net本来就会帮我们在app.config/web.config里生成各种配置,这没啥好研究的,但本文谈到的配置并不是这个.先看下面的图: 通常,如果采用.NET的WCF技 ...
- Winform开发框架的业务对象统一调用方式
在这个纷繁的社会里面,统一性的特点能够带来很多高效的产出.牢固的记忆,这种特征无论对于企业.个人的开发工作,知识的传承都有着非常重要的作用,Winfrom框架本身就是基于这个理念而生,从统一的数据库设 ...
- WCF寄宿方式
WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者 ...
- WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇]
原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇] 在<上篇>中,我通过使用Delegate的方式解决了服务调用过程中的异常处理以及对服务代理的关闭.对于<WCF技术 ...
- WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]
原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇] 在进行基于会话信道的WCF服务调用中,由于受到并发信道数量的限制,我们需要及时的关闭信道:当遇到某些异常,我们需要强行中止(Abor ...
- WCF引用方式
WCF之各种WCF引用方式 写在开头:本文内容来自 WCF全面解析中的一个经典例子,如果你已经看过了,那么可以忽略本文,本文旨在和大家分享不一样的WCF使用方法. 准备工作: 1.创建解决方案WCFS ...
- Restful风格wcf调用4——权限认证
写在前面 在前面的三篇文章,已经介绍了restful风格wcf,如何实现增删改查以及文件的上传下载操作.本篇文章将介绍一下,调用restful的权限认证的内容.在调用的接口,为了安全,总会需要对请求进 ...
- Restful风格wcf调用3——Stream
写在前面 上篇文章介绍了restful接口的增删改查,本篇文章将介绍,如何通过数据流进行文件的上传及下载操作. 系列文章 Restful风格wcf调用 Restful风格wcf调用2——增删改查 一个 ...
- 【转】java通用URL接口地址调用方式GET和POST方式
java通用URL接口地址调用方式GET和POST方式,包括建立请求和设置请求头部信息等等......... import java.io.ByteArrayOutputStream; import ...
随机推荐
- JavaScrip练习
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- windows7自动登录后锁定 & 其他VBS
首先设置自动登录(原已设置登录密码),在开始菜单搜索框输 入 “netplwiz” 按 回车,打开高级用户控制面板,然后取消对“要使用本机,用户需输入用户名和密码(E)”项的勾选,系统弹出窗口要求输入 ...
- 【python】python内存管理摘要
a = 1 id(a) == id(1) 每次退出ipython重新进入,这个Id都会不一样 sys.getrefcount(a) 可以计数某个对象的引用次数,是原来的次数+1 垃圾回收 使用gc包 ...
- scrapy 碎片
1.启动命令 2.目录结构 3.文件说明 4.架构图示 5.代码流程 参考资料: http://www.cnblogs.com/yangxt90/articles/9021530.html http: ...
- 原生JavaScript获取css样式
访问属性:obj.attr 或者 obj['attr'] 通过js访问style属性 : document.getElementById("main").style.backgro ...
- nginx 转发 由于php语法错误 导致的 50x
server { listen 8008; root /root/php-test; index index.php index.html index.htm ...
- kali视频(21-25)学习
第六周 kali视频(21-25)学习 21.密码攻击之在线攻击工具 22.密码攻击之离线攻击工具(一) 23.密码攻击之离线攻击工具(二) 24.密码攻击之哈希传递攻击 25.无线安全分析工具 21 ...
- 【1】基于quartz框架和Zookeeper实现集群化定时任务系统
(1)quartz本身可以支持集群化,是基于数据库做协调,现在构想基于zookeeper做协调实现集群化定时系统 流程图如下:
- nmon的使用
Linux性能评测工具之一:nmon篇 分类: 敏捷实践2010-06-08 11:27 7458人阅读 评论(0) 收藏 举报 工具linuxfilesystemsaixx86excel 目录( ...
- lvs之 lvs+nginx+tomcat_1、tomcat_2+redis(lvs dr 模式)
前提:已经安装好 lvs+nginx+tomcat_1.tomcat_2+redis环境 ,可参考 (略有改动,比如tomcat_1.tomcat_2安装在两台机器上,而不是单机多实例 ,自行稍稍变动 ...