WCF入门初体验
初次接触WCF,对它有点陌生、有点兴奋。今天做个简单的入门,逐步进入WCF的世界,感受她的呼吸和心跳。让我们一起进入正题吧。
今天咱们就了解创建WCF服务和客户端应用程序所需要的步骤。服务是一种构造,它公开一个或多个终结点,每个终结点都可以公开一项或多项服务操作。服务的终结点包含:服务所在的位置;一个绑定,其中包含客户端必须与服务端进行通信的信息;一个协定,用于定义服务向客户端提供的功能。
1.定义服务协定,也就是咱们通常说的接口,代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.ServiceModel; 6 7 namespace ServiceModeExample 8 { 9 /// <summary> 10 /// 定义服务协定 11 /// </summary> 12 //显示指定命名空间,这样可以防止默认命名空间值添加到协定名称 13 [ServiceContract(Namespace = "http://ServiceModeExample")] 14 public interface ICalculator 15 { 16 [OperationContract] 17 double Add(double n1, double n2); 18 19 [OperationContract] 20 double SubTract(double n1, double n2); 21 22 [OperationContract] 23 double Multiply(double n1, double n2); 24 25 [OperationContract] 26 double Divide(double n1, double n2); 27 } 28 }
定义此协定需要添加System.ServiceModel.dll引用,OperationContract表示定义一个操作,此操作是应用程序服务协定的一部分。
2.写到这里,我想大家一看也知道接来下需要做什么了,既然定义了服务协定,自然要实现服务协定了。创建一个新类CalculatorService,使其继承刚才定义的服务协定。实现服务协定内的逻辑。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace ServiceModeExample 7 { 8 /// <summary> 9 /// 实现服务协定 10 /// </summary> 11 public class CalculatorService:ICalculator 12 { 13 public double Add(double n1, double n2) 14 { 15 double result = n1 + n2; 16 Console.WriteLine("Received Add ({0},{1})",n1,n2); 17 Console.WriteLine("Return:{0}",result); 18 return result; 19 } 20 21 public double SubTract(double n1, double n2) 22 { 23 double result = n1 + n2; 24 Console.WriteLine("Received SubTract ({0},{1})", n1, n2); 25 Console.WriteLine("Return:{0}", result); 26 return result; 27 } 28 29 public double Multiply(double n1, double n2) 30 { 31 double result = n1 + n2; 32 Console.WriteLine("Received Multiply ({0},{1})", n1, n2); 33 Console.WriteLine("Return:{0}", result); 34 return result; 35 } 36 37 public double Divide(double n1, double n2) 38 { 39 double result = n1 + n2; 40 Console.WriteLine("Received Divide ({0},{1})", n1, n2); 41 Console.WriteLine("Return:{0}", result); 42 return result; 43 } 44 } 45 }
3.承载和运行基本的服务 包含为服务创建基址,为服务创建服务主机,启用元数据交换和打开服务主机
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.ServiceModel; 6 using System.ServiceModel.Description; 7 8 namespace ServiceModeExample 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 //承载运行基本的基址 15 Uri baseAddress = new Uri("http://localhost:8020/ServiceModeExample/Service"); 16 17 //创建一个新的实例以承载服务 必须指定实现服务协定和基址的类型 18 ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress); 19 20 try 21 { 22 //添加公开服务的终结点 必须指定终结点公开的协议,绑定和终结点的地址 23 selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService"); 24 25 //启用元数据交换 添加服务元数据行为 26 ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); 27 smb.HttpGetEnabled = true; 28 selfHost.Description.Behaviors.Add(smb); 29 30 //打开ServiceHost 并等待传入消息,用户按Enter键时,关闭ServiceHost 31 selfHost.Open(); 32 33 Console.WriteLine("The service is ready."); 34 Console.WriteLine("Press <Enter> to terminate service"); 35 Console.WriteLine(); 36 Console.ReadLine(); 37 38 selfHost.Close(); 39 } 40 catch (CommunicationException ex) 41 { 42 Console.WriteLine("An exception occurred: {0}", ex.Message); 43 selfHost.Abort(); 44 } 45 } 46 } 47 }
到此服务端的逻辑都已完成,运行起来,看看效果如何

说明服务运行正常。
4.创建客户端 在同一解决方案中添加新的项目,命名为Client,添加System.ServiceModel引用,客户端的代码我们可以直接用工具生成。
在“开始”菜单上,单击“所有程序”,然后单击“Visual Studio 2010”。单击“Visual Studio 工具”,然后单击“Visual Studio 2010 命令提示”。
- 导航到要放置客户端代码的目录。如果使用默认值创建客户端项目,则该目录为 C:\Users\<用户名>\My Documents\Visual Studio 10\Projects\Service\Client。
- 将命令行工具"ServiceModel元数据使用工具(Svcutil.exe)"与适当的开关一起使用以创建客户端代码。下面的示例生成服务的代码文件和配置文件。
默认情况下,将在一个以服务命名的文件(例如,在本示例中将为 CalculatorService.cs,其扩展名与.cs 生成客户端代理代码。/out 开关会将客户端代理文件的名称更改为 GeneratedProxy.cs。/config 开关会将客户端配置文件的名称从默认的 Output.config 更改为 App.config。请注意,这些文件都是在 C:\Users\<用户名>\My Documents\Visual Studio 10\Projects\Service\Client 目录中生成的。
svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config http://localhost:8020/ServiceModeExample/Service
在 Visual Studio 中将生成的代理添加到该客户端项目中,方法是在“解决方案资源管理器”中右击该客户端项目,选择“添加”,然后选择“现有项”。选择上面的步骤中生成的“generatedProxy”文件
5.配置客户端
在 Visual Studio 中,将生成的 App.config 配置文件添加到客户端项目中。
-
打开生成的配置文件。Svcutil.exe 会为绑定上的每一项设置都生成值。下面的示例显示了生成的配置文件。请在 <system.serviceModel><endpoint> 节下查找 元素。下面的配置文件是所生成的文件的简化版本。
- <?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICalculator" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8020/ServiceModeExample/Service/CalculatorService"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculator"
contract="ICalculator" name="WSHttpBinding_ICalculator">
<identity>
<userPrincipalName value="office.cn" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
此示例配置的终结点可供客户端在访问位于以下地址的服务时使用:http://localhost:8020/ServiceModeExample/Service/CalculatorService
终结点元素指定 ServiceModeExample.ICalculator协定将用于通过系统提供的 WsHttpBinding 配置的通信。此绑定指定 HTTP 作为传输协议、可互操作安全性以及其他配置详细信息。
6.最后一步 使用客户端
此过程执行三项操作:创建WCF客户端、从生成的代理调用服务操作和在完成操作调用后关闭客户端
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Client 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 //Step 1: Create an endpoint address and an instance of the WCF Client. 13 CalculatorClient client = new CalculatorClient(); 14 // Step 2: Call the service operations. 15 // Call the Add service operation. 16 double value1 = 100.00D; 17 double value2 = 15.99D; 18 double result = client.Add(value1, value2); 19 Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result); 20 21 // Call the Subtract service operation. 22 value1 = 145.00D; 23 value2 = 76.54D; 24 result = client.SubTract(value1, value2); 25 Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result); 26 27 // Call the Multiply service operation. 28 value1 = 9.00D; 29 value2 = 81.25D; 30 result = client.Multiply(value1, value2); 31 Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result); 32 33 // Call the Divide service operation. 34 value1 = 22.00D; 35 value2 = 7.00D; 36 result = client.Divide(value1, value2); 37 Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result); 38 39 //Step 3: Closing the client gracefully closes the connection and cleans up resources. 40 client.Close(); 41 42 43 Console.WriteLine(); 44 Console.WriteLine("Press <ENTER> to terminate client."); 45 Console.ReadLine(); 46 47 } 48 } 49 }
到此为止,所有工作已经做好,费用了那么大的劲,看看效果如何?
服务端:

客户端:



浙公网安备 33010602011771号