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<stringstring> 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<stringstring> 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<stringstring> 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<stringstring>(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调用方式的更多相关文章

  1. Wcf:可配置的服务调用方式

    添加wcf服务引用时,vs.net本来就会帮我们在app.config/web.config里生成各种配置,这没啥好研究的,但本文谈到的配置并不是这个.先看下面的图: 通常,如果采用.NET的WCF技 ...

  2. Winform开发框架的业务对象统一调用方式

    在这个纷繁的社会里面,统一性的特点能够带来很多高效的产出.牢固的记忆,这种特征无论对于企业.个人的开发工作,知识的传承都有着非常重要的作用,Winfrom框架本身就是基于这个理念而生,从统一的数据库设 ...

  3. WCF寄宿方式

    WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者 ...

  4. WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇]

    原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇] 在<上篇>中,我通过使用Delegate的方式解决了服务调用过程中的异常处理以及对服务代理的关闭.对于<WCF技术 ...

  5. WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]

    原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇] 在进行基于会话信道的WCF服务调用中,由于受到并发信道数量的限制,我们需要及时的关闭信道:当遇到某些异常,我们需要强行中止(Abor ...

  6. WCF引用方式

    WCF之各种WCF引用方式 写在开头:本文内容来自 WCF全面解析中的一个经典例子,如果你已经看过了,那么可以忽略本文,本文旨在和大家分享不一样的WCF使用方法. 准备工作: 1.创建解决方案WCFS ...

  7. Restful风格wcf调用4——权限认证

    写在前面 在前面的三篇文章,已经介绍了restful风格wcf,如何实现增删改查以及文件的上传下载操作.本篇文章将介绍一下,调用restful的权限认证的内容.在调用的接口,为了安全,总会需要对请求进 ...

  8. Restful风格wcf调用3——Stream

    写在前面 上篇文章介绍了restful接口的增删改查,本篇文章将介绍,如何通过数据流进行文件的上传及下载操作. 系列文章 Restful风格wcf调用 Restful风格wcf调用2——增删改查 一个 ...

  9. 【转】java通用URL接口地址调用方式GET和POST方式

    java通用URL接口地址调用方式GET和POST方式,包括建立请求和设置请求头部信息等等......... import java.io.ByteArrayOutputStream; import ...

随机推荐

  1. UI-UIScrollView

    - (void)viewDidLoad { [super viewDidLoad]; scrollView = [[UIScrollView alloc] initWithFrame:CGRectMa ...

  2. react table dropdown

    <DropdownButton type="primary" trigger={['click']} onClick={() => this.detail(item)} ...

  3. NODE 性能优化

    五个手段 “如果你的 node 服务器前面没有 nginx, 那么你可能做错了.”—Bryan Hughes Node.js 是使用 最流行的语言— JavaScript 构建服务器端应用的领先工具 ...

  4. Java学习笔记——基础篇

    Tips1:eclipse中会经常用到System.out.println方法,可以先输入syso,然后eclipse就会自动联想出这个语句了!! 学习笔记: *包.权限控制 1.包(package) ...

  5. Freemarker Failed at: ${itm.creatTimeString?string("yyyy-MM... [in template

    p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'Helvetica Neue'; color: #454545} p.p2 {margin: ...

  6. TensorFlow官网访问不了

    相信很多搞深度学习的小伙伴最近都为访问不了 TensorFlow官网 而苦恼吧!虽然网上也给出了一些方法,但是却缺少一个很重要的步骤.接下来,我就给大家讲解一个完整的过程,大牛绕过. 1.更改Host ...

  7. C++ Primer 第四版中文版

    C++Primer是C++的经典教程. 开始时间:2014-08-10 完成时间:2014-08-28 学习成果:基础语法+

  8. 51nod 1298 圆与三角形

    给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交.相交输出"Yes",否则输出"No".(三角形的面积大于0).       输入 第1行:一个数 ...

  9. .NET程序如何启动?

    .net程序如何启动? .NET Framework在Windows平台顶部运行,这意味着.NET Framework必须使用 windows可以理解的技术来构建.首先,所有托管模块和程序集文件都必须 ...

  10. 7天学会HTML--HTML综述

    一周学会HTML 1.HTML是什么? HTML 指的是超文本标记语言 (Hyper Text Markup Language) 2.HTML发展历程 HTML版本从1.0到4.0不断升级,其版本的规 ...