构建一个简单的WCF应用
2013-04-13 09:43
579 查看
本应用的功能虽然简单,但它具有一个完整的WCF应用的基本结构。应用实现一个简单的计算服务来提供基本的加、减、乘、除运算。
1、构建整个解决方案
创建一个空白的解决方案WcfServices,并添加如下项目:
(1)Service.Interface:用于定义服务契约(Service Contract)的类库项目,引用WCF的核心程序集System.ServiceModel.dll。
(2)Service:用于定义服务类型的类库项目。由于服务类型需要实现定义在Service.Interface中的相应的契约接口,因此该项目具有Service.Interface项目引用。
(3)Hosting:作为服务寄主的控制台应用。该项目同时引用Service.Interface、Service项目和System.ServiceModel.dll程序集。
(4)Client:一个控制台应用模拟服务的客户端,该项目引用System.ServiceModel.dll程序集。
2、创建服务契约
在Service.Interface项目中创建ICalculator.cs接口类。
3、创建服务
在Service项目中创建CalculatorService.cs类,并实现ICalculator接口
4、通过自我寄宿的方式寄宿服务
WCF服务需要依存一个运行着的宿主进程,服务寄宿就是为服务指定一个宿主的过程。
在Hosting项目中创建MyServiceHost.cs类,这里分别以:代码编写、读取XML服务配置的形式创建寄宿服务。
4.1 通过代码编写创建服务程序
4.2 通过读取XML服务配置创建服务程序
4.2.1 编写App.config配置文件
4.2.2 修改MyServiceHost.cs类中的方法
如果采用读取XML配置的形式,服务寄宿代码将会得到极大的精简。
4.3 运行服务
5、创建客户端调试服务
5.1 导出服务代理相关代码和相应的配置
服务被成功寄宿后,服务端便开始了服务调用请求的监听。借助代码生成工具(SvcUtil.exe)自动生成服务调用的服务代理相关代码和相应的配置。
(1)获取服务代理相关代码(CalculatorService.cs)
5.1 通过代码创建客户端
5.2 通过读取配置方式创建客户端
6、通过IIS寄宿服务
前面演示了将控制台应用作为服务寄主的自我寄宿方式,下面来演示如何将IIS作为服务的寄主。
6.1 创建Web应用
创建名为WcfService的web应用程序。
(1) 创建.svc文件
(3)将网站部署到IIS
6.2 客户端调用服务
(1)导出服务代理相关代码和相应的配置
通过地址:svcutil.exe http://localhost:11477/CalculatorService.svc?wsdl,借助代码生成工具导出服务代理相关代码和相应的配置。
得到服务代理相关代码和相应的配置后,客户端的调用就与本文上述的调用方式是一样的。
(本文的实例参考于蒋金楠老师的《WCF全面解析》书中的例子)
1、构建整个解决方案
创建一个空白的解决方案WcfServices,并添加如下项目:
(1)Service.Interface:用于定义服务契约(Service Contract)的类库项目,引用WCF的核心程序集System.ServiceModel.dll。
(2)Service:用于定义服务类型的类库项目。由于服务类型需要实现定义在Service.Interface中的相应的契约接口,因此该项目具有Service.Interface项目引用。
(3)Hosting:作为服务寄主的控制台应用。该项目同时引用Service.Interface、Service项目和System.ServiceModel.dll程序集。
(4)Client:一个控制台应用模拟服务的客户端,该项目引用System.ServiceModel.dll程序集。
2、创建服务契约
在Service.Interface项目中创建ICalculator.cs接口类。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Service.Interface { [ServiceContract] public interface ICalculator { [OperationContract] double Add(double x, double y); [OperationContract] double Subtract(double x, double y); [OperationContract] double Multiply(double x, double y); [OperationContract] double Divide(double x, double y); } }
3、创建服务
在Service项目中创建CalculatorService.cs类,并实现ICalculator接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Service.Interface; namespace Service { public class CalculatorService:ICalculator { public double Add(double x, double y) { return x + y; } public double Subtract(double x, double y) { return x - y; } public double Multiply(double x, double y) { return x * y; } public double Divide(double x, double y) { return x / y; } } }
4、通过自我寄宿的方式寄宿服务
WCF服务需要依存一个运行着的宿主进程,服务寄宿就是为服务指定一个宿主的过程。
在Hosting项目中创建MyServiceHost.cs类,这里分别以:代码编写、读取XML服务配置的形式创建寄宿服务。
4.1 通过代码编写创建服务程序
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using Service; using Service.Interface; namespace Hosting { /// <summary> /// 服务寄宿类 /// </summary> public class MyServiceHost : IDisposable { public ServiceHost myHost; //服务 private const string serviceAddressUrl = "http://127.0.0.1:3721/CalculatorService"; //服务地址 private const string serviceMetadataUrl = "http://127.0.0.1:3721/CalculatorService/metadata"; //元数据发布的源地址 /// <summary> /// 初始化 /// </summary> public MyServiceHost() { ConstructSericeHost(); } /// <summary> /// 创建服务通过代码方式 /// </summary> public void ConstructSericeHost() { //1、初始化ServiceHost对象 myHost = new ServiceHost(typeof(CalculatorService)); //2、添加一个终结点(终结点由:地址、绑定、契约组成) Uri address = new Uri(serviceAddressUrl); //地址 Binding binding = new BasicHttpBinding(); //绑定 Type serviceType = typeof(ICalculator); //契约 myHost.AddServiceEndpoint(serviceType, binding, address); //3、添加元数据发布行为 if (myHost.Description.Behaviors.Find<ServiceMetadataBehavior>() == null) { ServiceMetadataBehavior metadataBehavior = new ServiceMetadataBehavior(); metadataBehavior.HttpGetEnabled = true; metadataBehavior.HttpGetUrl = new Uri(serviceMetadataUrl); myHost.Description.Behaviors.Add(metadataBehavior); } } /// <summary> /// 打开服务 /// </summary> public void Open() { Console.WriteLine("开始启动服务..."); myHost.Open(); Console.WriteLine("服务已启动..."); } /// <summary> /// 关闭服务 /// </summary> public void Dispose() { if (myHost != null) { (myHost as IDisposable).Dispose(); Console.WriteLine("服务已关闭..."); } } } }
4.2 通过读取XML服务配置创建服务程序
4.2.1 编写App.config配置文件
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="Service.CalculatorService" behaviorConfiguration="metadataBehavior"> <endpoint address="http://127.0.0.1:3721/CalculatorService" binding="basicHttpBinding" contract="Service.Interface.ICalculator"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:3721/CalculatorService/metadata"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
4.2.2 修改MyServiceHost.cs类中的方法
如果采用读取XML配置的形式,服务寄宿代码将会得到极大的精简。
/// <summary> /// 创建服务通过读取XML方式 /// </summary> public void ConstructSericeHost() { //初始化ServiceHost对象 myHost = new ServiceHost(typeof(CalculatorService)); }
4.3 运行服务
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.ServiceModel.Description; using Service; using Service.Interface; namespace Hosting { class Program { static void Main(string[] args) { try { //由于MySerivceHost实现了IDisposable接口,所以使用using using (MyServiceHost host = new MyServiceHost()) { host.Open(); Console.Read(); } } catch (Exception e) { Console.WriteLine(e.ToString()); Console.Read(); } } } }
5、创建客户端调试服务
5.1 导出服务代理相关代码和相应的配置
服务被成功寄宿后,服务端便开始了服务调用请求的监听。借助代码生成工具(SvcUtil.exe)自动生成服务调用的服务代理相关代码和相应的配置。
(1)获取服务代理相关代码(CalculatorService.cs)
//------------------------------------------------------------------------------ // <auto-generated> // 此代码由工具生成。 // 运行时版本:2.0.50727.4984 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ICalculator")] public interface ICalculator { [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculator/Add", ReplyAction="http://tempuri.org/ICalculator/AddResponse")] double Add(double x, double y); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculator/Subtract", ReplyAction="http://tempuri.org/ICalculator/SubtractResponse")] double Subtract(double x, double y); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculator/Multiply", ReplyAction="http://tempuri.org/ICalculator/MultiplyResponse")] double Multiply(double x, double y); [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ICalculator/Divide", ReplyAction="http://tempuri.org/ICalculator/DivideResponse")] double Divide(double x, double y); } [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public interface ICalculatorChannel : ICalculator, System.ServiceModel.IClientChannel { } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class CalculatorClient : System.ServiceModel.ClientBase<ICalculator>, ICalculator { public CalculatorClient() { } public CalculatorClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public CalculatorClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public double Add(double x, double y) { return base.Channel.Add(x, y); } public double Subtract(double x, double y) { return base.Channel.Subtract(x, y); } public double Multiply(double x, double y) { return base.Channel.Multiply(x, y); } public double Divide(double x, double y) { return base.Channel.Divide(x, y); } }(2)获取相应的配置(App.config)
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_ICalculator" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://127.0.0.1:3721/CalculatorService" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ICalculator" contract="ICalculator" name="BasicHttpBinding_ICalculator" /> </client> </system.serviceModel> </configuration>
5.1 通过代码创建客户端
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Client { class Program { static void Main(string[] args) { //使用代码设置信息 BasicHttpBinding bind = new BasicHttpBinding(); bind.Security.Mode = BasicHttpSecurityMode.None; EndpointAddress edp = new EndpointAddress("http://127.0.0.1:3721/CalculatorService"); CalculatorClient client = new CalculatorClient(bind, edp); double result = client.Add(3, 4); client.Close(); Console.Write(result); Console.Read(); } } }
5.2 通过读取配置方式创建客户端
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Client { class Program { static void Main(string[] args) { //使用读取配置方式创建客户端 CalculatorClient client = new CalculatorClient("BasicHttpBinding_ICalculator"); double result = client.Add(3, 7); client.Close(); Console.Write(result); Console.Read(); } } }
6、通过IIS寄宿服务
前面演示了将控制台应用作为服务寄主的自我寄宿方式,下面来演示如何将IIS作为服务的寄主。
6.1 创建Web应用
创建名为WcfService的web应用程序。
(1) 创建.svc文件
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; using Service.Interface; namespace WcfService { // 注意: 如果更改此处的类名 "CalculatorService",也必须更新 Web.config 中对 "CalculatorService" 的引用。 public class CalculatorService : ICalculator { public double Add(double x, double y) { return x + y; } public double Subtract(double x, double y) { return x - y; } public double Multiply(double x, double y) { return x * y; } public double Divide(double x, double y) { return x / y; } } }(2) 在Web.config中添加服务配置
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="WcfService.CalculatorServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="WcfService.CalculatorServiceBehavior" name="WcfService.CalculatorService"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="" contract="Service.Interface.ICalculator"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> </system.serviceModel> </configuration>
(3)将网站部署到IIS
6.2 客户端调用服务
(1)导出服务代理相关代码和相应的配置
通过地址:svcutil.exe http://localhost:11477/CalculatorService.svc?wsdl,借助代码生成工具导出服务代理相关代码和相应的配置。
得到服务代理相关代码和相应的配置后,客户端的调用就与本文上述的调用方式是一样的。
(本文的实例参考于蒋金楠老师的《WCF全面解析》书中的例子)
相关文章推荐
- 构建一个简单的WCF应用
- 构建一个简单的WCF应用
- 构建一个简单的WCF应用——WCF学习笔记(1)
- 构建一个简单的WCF应用
- 构建一个简单的WCF应用
- Angular5初探之--构建一个简单的单页应用,包含登录(login)和几个一级菜单
- (WCF)示例一: 构建一个简单的WCF Service: MagicEightBall
- 微信小程序入门之构建一个简单TODOS应用
- 基于Vue2.0+Vue-router构建一个简单的单页应用
- 一步一个脚印学习WCF之二构建一个简单的WCF应用程序前必须掌握的WCF基础术语---契约(Contract)
- 学习构建一个简单的wcf服务
- 一步一个脚印学习WCF之二构建一个简单的WCF应用程序前必须掌握的WCF基础术语---契约的名称与命名空间
- 4 - Swift之2 - 使用xcode7构建一个简单的应用并在IOS9设备上真机运行
- 基于Vue2.0+Vue-router构建一个简单的单页应用
- 基于Vue2.0+Vue-router构建一个简单的单页应用
- 基于MINA构建简单高性能的NIO应用-一个简单的例子
- 微信小程序入门之构建一个简单TODOS应用
- 通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用
- 重温WCF之构建一个简单的WCF(一)(1)通过控制台和IIS寄宿服务
- 微信小程序入门之构建一个简单TODOS应用