WCF入门--纯代码实现启动及引用WCF

时间:2020-12-19 16:48:12



这几天趁着闲着就开始学习WCF,上网找了很多资料看,结果都是要这个资料对应那个资料的,感觉很不方便,现写下自己的一些总结,希望能帮助到想入门WCF的朋友。



       主要参考文献:地址: http://msdn.microsoft.com/en-us/library/ms734712.aspx


       创建一个WCF主要分以下六步走:


    (MSDN描述步骤:)    


       如何:定义 Windows Communication Foundation 服务协定 
描述如何使用用户定义的接口创建 WCF 协定。协定用于定义服务向外界提供的功能,并向外界的潜在用户描述如何与服务进行通信。


      如何:实现 Windows Communication Foundation 服务协定 
描述如何实现服务协定。创建了协定后,必须在一个从定义协定的接口继承的类中实现服务所提供的功能。


      如何:承载和运行基本的 Windows Communication Foundation 服务 
描述如何在代码中配置服务的终结点,以及如何在控制台应用程序内承载服务和启动服务。若要激活服务,必须在运行时环境中配置和承载服务。此环境将创建服务并控制其上下文和生存期。


      如何:创建 Windows Communication Foundation 客户端 
描述如何从 WCF 服务检索用于创建 WCF 客户端的元数据。此过程使用由 WCF 提供的 ServiceModel 元数据实用工具 (Svcutil.exe)。


      如何:配置基本 Windows Communication Foundation 客户端 
描述如何配置使用 ServiceModel 元数据实用工具 (Svcutil.exe) 创建的基本客户端。配置客户端需要指定客户端用于访问服务的终结点。


      如何:使用 Windows Communication Foundation 客户端 
描述如何使用 ServiceModel 元数据实用工具 (Svcutil.exe) 生成的 WCF 客户端代理来调用服务所提供的功能。      
      具体实现步骤如下:


      先建立一个解决方案。
      在这个解决方案下面建立一个叫做Server的控制台应用项目,再建立一个叫做Client的控制台应用项目。
      分别给每一个项目添加引用到System.ServiceModel


     创建基本 WCF 服务时,第一项任务是定义协定。协定指定服务支持的操作。可以将操作视为一个 Web 服务方法。通过定义 C++、C# 或 VB 接口可创建协定。接口中的每个方法都对应于特定的服务操作。每个接口都必须将 ServiceContractAttribute 应用于自身,而每个操作都必须将 OperationContractAttribute 应用于自身。如果接口中的一个方法具有 ServiceContractAttribute 而没有 OperationContractAttribute,则不公开该方法。


     创建好Server后,将默认的Service命名空间更改为Microsoft.ServiceModel.Samples。


     编辑Server的Program(注意记得using System.ServiceModel和using System.ServiceModel.Description)


    Server端的Program代码如下:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Microsoft.ServiceModel.Samples
{
//定义接口契约(MSDN第一步:定义服务协定)
//定义一个名为 ICalculator 的新接口,并向该接口应用 Namespace 值为“http://Microsoft.ServiceModel.Samples”的 ServiceContractAttribute 属性。显式指定命名空间是一种最佳做法,因为这样可防止将默认命名空间值添加到协定名称。
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
//以下是定义加减乘除的四个方法
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);

}

//实现接口(MSDN第二步:实现服务协定)
public class CalculatorService : ICalculator
{
public double Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Multiply(double n1, double n2)
{
double result = n1 * n2;
Console.WriteLine("Received Multiply({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Divide(double n1, double n2)
{
double result = n1 / n2;
Console.WriteLine("Received Divide({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

}

class Program
{
static void Main(string[] args)
{
//承载和运行服务(MSDN第三步)
//为服务配置基址
//1.为服务的基址创建 Uri 实例。此 URI 指定 HTTP 方案、本地计算机、端口号 8000,以及服务协定中为服务命名空间指定的服务路径 ServiceModelSample/Service。
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");

//承载服务
//1.导入 System.ServiceModel.Description 命名空间。这行代码应该与 using 或 imports 语句的其余部分一起放置在 Program.cs/Program.vb 文件的顶部。
//2.创建一个新的 ServiceHost 实例以承载服务。必须指定实现服务协定和基址的类型。对于此示例,基址为 http://localhost:8000/ServiceModelSamples/Service,CalculatorService 为实现服务协定的类型。
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
//3.添加一个捕获 CommunicationException 的 try-catch 语句,并在接下来的三个步骤中将该代码添加到 try 块中。catch 子句应该显示错误信息,然后调用 selfHost.Abort()。
try
{
//4.添加公开服务的终结点。为此,必须指定终结点公开的协议、绑定和终结点的地址。对于此示例,将 ICalculator 指定为协定,将 WSHttpBinding 指定为绑定,并将 CalculatorService 指定为地址。在这里请注意,终结点地址是相对地址。终结点的完整地址是基址和终结点地址的组合。在此例中,完整地址是 http://localhost:8000/ServiceModelSamples/Service/CalculatorService。
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
//5.启用元数据交换。为此,添加服务元数据行为。首先创建一个 ServiceMetadataBehavior 实例,将 HttpGetEnabled 属性设置为 true,然后为服务添加新行为。
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
//6.打开 ServiceHost 并等待传入消息。用户按 Enter 键时,关闭 ServiceHost
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();

selfHost.Close();
}
catch(CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
}
}
}


     到此,服务端就配好了


     验证服务是否正常运行


     1.从 Visual Studio 内部运行 service.exe。在 Windows Vista 上运行时,必须使用管理员特权运行服务。由于 Visual Studio 是使用管理员特权运行的,因此 service.exe 也是使用管理员特权运行的。也可以启动新的命令提示,使用管理员特权运行它,并在其中运行 service.exe。


      2.打开 Internet Explorer,并浏览到服务的调试页(网址为 http://localhost:8000/ServiceModelSamples/Service)。


配置创建的客户端:(创建客户端就是MSDN中的第四步)


步骤:(下面就是MSDN中的第五步,配置客户端)


1.首先运行写好的服务端,可在项目中按F5运行


2.在“开始”菜单上,单击“所有程序”,然后单击“Visual Studio 2008”。单击“Visual Studio 工具”,然后单击“Visual Studio 2008 命令提示”。


3.导航到要放置客户端代码的目录。例如: 


4.生成文件,命令如下:

D:\WCF\WCFDEMO\WCFSample\Client>svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config http://localhost:8000/ServiceModelSamples/service
5.把生成后的App.config 和generatedProxy.cs 文件添加到Client的项目中


最后就是使用客户端了(MSDN中的第六步)


Client的Program代码如下:
using System;
using System.ServiceModel;

namespace Client
{
class Program
{
static void Main(string[] args)
{
//Step 1: Create an endpoint address and an instance of the WCF Client.
//为要调用的服务的基址创建 EndpointAddress 实例,然后创建 WCF Client 对象。
EndpointAddress epAddress = new EndpointAddress("http://localhost:8000/ServiceModelSamples/Service/CalculatorService");
CalculatorClient client = new CalculatorClient(new WSHttpBinding(), epAddress);


// Step 2: Call the service operations.
//从 Client 内调用客户端操作。
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

// Call the Subtract service operation.
value1 = 145.00D;
value2 = 76.54D;
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

// Call the Multiply service operation.
value1 = 9.00D;
value2 = 81.25D;
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

// Call the Divide service operation.
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

//Step 3: Closing the client gracefully closes the connection and cleans up resources.
//在 WCF 客户端上调用 Close 并等待,直到用户按 Enter 终止应用程序。
client.Close();

Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();

}
}
}

  到此,整个服务端和客户端都写好了


   验证服务是否正常运行


1.首先找到项目里面已编译好的服务端,例如:D:\WCF\WCFDEMO\WCFSample\Server\bin\Debug,启动里面的Server.EXE


2.启动客户端,可以是启动解决方案中的Client,按F5启动,如果看到如下结果,证明已成功了

Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Press <ENTER> to terminate client.


整个的项目结构如截图:

WCF入门--纯代码实现启动及引用WCF

http://blog.163.com/glq_19/blog/static/127417581201052875239622/