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)"与适当的开关一起使用以创建客户端代码。下面的示例生成服务的代码文件和配置文件。
    svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config http://localhost:8020/ServiceModeExample/Service
    默认情况下,将在一个以服务命名的文件(例如,在本示例中将为 CalculatorService.cs,其扩展名与.cs 生成客户端代理代码。/out 开关会将客户端代理文件的名称更改为 GeneratedProxy.cs。/config 开关会将客户端配置文件的名称从默认的 Output.config 更改为 App.config。请注意,这些文件都是在 C:\Users\<用户名>\My Documents\Visual Studio 10\Projects\Service\Client 目录中生成的。

       在 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 }

到此为止,所有工作已经做好,费用了那么大的劲,看看效果如何?
服务端:

客户端:

 

posted @ 2012-08-07 15:59  仪涵2012  阅读(942)  评论(0)    收藏  举报