收藏 分销(赏)

WCF入门教程.doc

上传人:pc****0 文档编号:9011621 上传时间:2025-03-11 格式:DOC 页数:30 大小:693.50KB 下载积分:10 金币
下载 相关 举报
WCF入门教程.doc_第1页
第1页 / 共30页
WCF入门教程.doc_第2页
第2页 / 共30页


点击查看更多>>
资源描述
我们通过实现一个简单的示例来对WCF有个直观而浅显的认识,希望对初次涉及WCF的朋友有所帮助。 可以简单地认为WCF程序分为4部分:契约、服务、宿主、客户端。我们通过一个例子来逐步完成各部分,示例程序中,客户端可以获取一个信息列表,列表中每一项包括ID、值、读值时刻、状态、状态变动时刻。这里我用的是VS2010。  首先,创建一个空白解决方案WCFDemo。 我们将在其中添加n个项目,分别实现契约、服务、宿主、客户端。如果用VS2010新建“WCF服务库”或者“WCF服务应用程序”,它会默认把契约和服务放在一个项目中,我们这个示例把契约和服务分别放在2个类库项目中。  第一步:契约   1、添加一个类库WCFDemo.Contracts。   2、在类库中添加2个文件DataContracts.cs和ServiceContracts.cs,分别放置数据契约和服务契约。   3、添加引用System.Runtime.Serialization和System.ServiceModel。   4、编写代码如下: DataContracts.cs using System; using System.Runtime.Serialization; namespace WCFDemo.Contracts { [DataContract] public class DemoData { [DataMember] public int ID { get; set; } [DataMember] public double Value { get; set; } [DataMember] public DateTime ValueTime { get; set; } [DataMember] public DeviceState State { get; set; } [DataMember] public DateTime StateTime { get; set; } } public enum DeviceState { Unknown, Working, Broken } }   (题外话:DemoData类中各个属性的写法有些偷懒,其实个人不建议这样。这里是为了代码简单……) ServiceContracts.cs using System.Collections.Generic; using System.ServiceModel; namespace WCFDemo.Contracts { [ServiceContract] public interface IDemoService { [OperationContract] List<DemoData> GetMonitorData(); } }  第二步:服务   1、添加一个类库WCFDemo.Services。   2、在类库中加入一个文件Services.cs用来放置实现服务的类。   3、添加引用WCFDemo.Contracts。   4、编写代码如下:    using System; using System.Collections.Generic; using WCFDemo.Contracts; namespace WCFDemo.Services { public class DemoService : IDemoService { Random random = new Random(); public List<DemoData> GetMonitorData() { List<DemoData> r = new List<DemoData>(); r.Add(new DemoData() { ID = 1, Value = random.Next(100), ValueTime = DateTime.Now, State = DeviceState.Unknown, StateTime = DateTime.Now }); r.Add(new DemoData() { ID = 2, Value = random.Next(100), ValueTime = DateTime.Now, State = DeviceState.Working, StateTime = DateTime.Now }); r.Add(new DemoData() { ID = 3, Value = random.Next(100), ValueTime = DateTime.Now, State = DeviceState.Broken, StateTime = DateTime.Now }); return r; } } } (题外话:第一步时说过DemoData的偷懒写法。如果DemoData中针对每个属性定义私有字段,并提供带参数的构造函数,构造函数中对字段赋值而不是对属性赋值,那么每个DemoData实例化时比这里的示例代码效率高。)   到这里,服务和契约已经完成。  剩下的就是宿主如何对外提供服务和客户端如何享受服务了,我们先使用最最简单的方式来实现。  我们先以最简单的方式来实现宿主和客户端:直接引用契约和服务项目、采用硬编码的方式。   第三步:宿主   1、添加一个Windows窗体应用程序WCFDemo.Host.WithoutConfig。   2、添加引用System.ServiceModel。   3、引用之前的两个项目。   4、在窗体放置两个Button和一个Label,并编写代码如下: using System; using System.Windows.Forms; using System.ServiceModel; using WCFDemo.Services; using WCFDemo.Contracts; namespace WCFDemo.Host.WithoutConfig { public partial class HostForm : Form { public HostForm() { InitializeComponent(); } ServiceHost host; private void button1_Click(object sender, EventArgs e) { host = new ServiceHost(typeof(DemoService)); host.AddServiceEndpoint(typeof(IDemoService), new BasicHttpBinding(), "http://localhost:5678/DemoService"); host.Opened += delegate { label1.Text = "服务启动"; }; host.Open(); } private void button2_Click(object sender, EventArgs e) { if (host != null && host.State == CommunicationState.Opened) { host.Closed += delegate { label1.Text = "服务停止"; }; host.Close(); } } } }  第四步:客户端   1、添加一个Windows窗体应用程序WCFDemo.Client.WithoutConfig。   2、添加引用System.ServiceModel。   3、引用之前契约项目。   4、在窗体放置一个Button和一个DataGridView,并编写代码如下: using System; using System.Windows.Forms; using System.ServiceModel; using WCFDemo.Contracts; namespace WCFDemo.Client.WithoutConfig { public partial class ClientForm : Form { public ClientForm() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { using (ChannelFactory<IDemoService> f = new ChannelFactory<IDemoService>(new BasicHttpBinding(), "http://localhost:5678/DemoService")) { dataGridView1.DataSource = f.CreateChannel().GetMonitorData(); } } } }   到这里,已经完成了一个最简单的WCF程序,也涉及到了WCF的基本概念:终结点、ABC(地址、绑定、契约)……。 这个示例很简单(甚至简陋,而且编码风格和习惯也不好☺),只是用来初识WCF,要做的还有很多,下次继续…… 上一篇介绍了最简单的方式来实现宿主和客户端:直接引用契约和服务项目、采用硬编码的方式,这次通过配置文件来定义终结点。刚接触WCF时,直接编辑配置文件会让人一头雾水,所以还是使用直观的方式——使用WCF编辑工具,这个工具可以通过“开始”→“Microsoft Visual Studio 2010”→“Microsoft Windows SDK Tools”→“服务配置编辑器”打开,也可以通过VS2010的IDE中“工具”→“WCF服务配置编辑器”打开。 宿主:   1、在之前的解决方案中添加一个Windows窗体应用程序WCFDemo.Host.WithConfig。   2、添加引用System.ServiceModel。   3、引用上一篇的契约和服务两个项目。   4、为宿主项目添加应用程序配置文件,并编辑:   运行配置工具,打开宿主项目的配置文件,右击树形目录的“服务”节点新建服务;    把Name属性设置为我们之前写的服务;    新建服务终结点,并设置A(Address)、B(Binding)、C(Contract)。设置的值和上一篇代码里的一样;    保存后可以查看配置文件。 <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="WCFDemo.Services.DemoService"> <endpoint address="http://localhost:5678/DemoService" binding="basicHttpBinding" bindingConfiguration="" contract="WCFDemo.Contracts.IDemoService" /> </service> </services> </system.serviceModel> </configuration>   5、在窗体放置两个Button和一个Label,编写代码如下: using System; using System.Windows.Forms; using System.ServiceModel; using WCFDemo.Services; namespace WCFDemo.Host.WithConfig { public partial class HostWithConfigForm : Form { public HostWithConfigForm() { InitializeComponent(); } ServiceHost host; private void button1_Click(object sender, EventArgs e) { host = new ServiceHost(typeof(DemoService)); host.Opened += delegate { label1.Text = "服务启动"; }; host.Open(); } private void button2_Click(object sender, EventArgs e) { if (host != null && host.State == CommunicationState.Opened) { host.Closed += delegate { label1.Text = "服务停止"; }; host.Close(); } } } } 可以发现,和之前唯一不同就是少了添加服务终结点的代码。运行带配置的宿主程序,再运行之前的客户端程序,可以正常通讯。接下来看一下使用配置文件的客户端。   客户端:   1、在之前的解决方案中添加一个Windows窗体应用程序WCFDemo.Client.WithConfig。   2、添加引用System.ServiceModel。   3、引用之前契约项目。   4、为客户端项目添加应用程序配置文件,并编辑:   运行配置工具,打开客户端项目的配置文件,右击树形目录的“客户端”→“终结点”节点新建客户端终结点,并设置ABC和Name:  保存后可以查看配置文件: <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <endpoint address="http://localhost:5678/DemoService" binding="basicHttpBinding" bindingConfiguration="" contract="WCFDemo.Contracts.IDemoService" name="DemoService" /> </client> </system.serviceModel> </configuration>   5、在窗体放置一个Button和一个DataGridView,并编写代码如下: using System; using System.Windows.Forms; using System.ServiceModel; using WCFDemo.Contracts; namespace WCFDemo.Client.WithConfig { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { using (ChannelFactory<IDemoService> channelFactory = new ChannelFactory<IDemoService>("DemoService")) { dataGridView1.DataSource = channelFactory.CreateChannel().GetMonitorData(); } } } } 代码中ChannelFactory构造函数的参数和配置文件中的Name要一致。   现在,使用配置文件和不使用配置文件的宿主及客户端已完成,两个服务器和两个客户端之间都可通讯。看得出来,客户端使用服务都是对某个终结点的,客户端的ABC要和服务端一致。 目前为止,客户端都是通过直接引用契约类库来使用WCF服务的,很多时候客户端无法直接引用契约类库,这就需要服务端发布自己的契约,客户端根据契约生成代理类。 如何实现,下一篇再说——简短一点儿好。 之前两篇随笔的示例中客户端直接引用契约类库,现实中可能因为开发团队或语言等原因,客户端不能直接引用契约类库,这就需要服务端公布自己的契约、客户端发现契约。 服务端: 服务端通过配置服务行为,以元数据的形式公布服务。可以使用配置文件也可以使用代码。 1、使用配置文件: 将之前的WCFDemo.Host.WithConfig项目的配置文件用WCF服务配置编辑器打开,新建服务行为配置: 这里就用默认的Name,实际项目中起个好听的名字吧☺ 添加服务元数据: 设置元数据的HttpGetEnabled和HttpGetUrl: 选择服务,设置其BehaviorConfiguration为刚添加的服务行为: 保存后的配置文件: <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="NewBehavior0"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:5678/DemoService/metadata" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="NewBehavior0" name="WCFDemo.Services.DemoService"> <endpoint address="http://localhost:5678/DemoService" binding="basicHttpBinding" bindingConfiguration="" contract="WCFDemo.Contracts.IDemoService" /> </service> </services> </system.serviceModel> </configuration> 使用配置文件的方式,程序代码不需要任何修改。 2、代码方式: 在WCFDemo.Host.WithoutConfig项目的启动服务代码处添加服务行为的处理代码: host = new ServiceHost(typeof(DemoService)); host.AddServiceEndpoint(typeof(IDemoService), new BasicHttpBinding(), "http://localhost:5678/DemoService"); ServiceMetadataBehavior b = new ServiceMetadataBehavior(); b.HttpGetEnabled = true; b.HttpGetUrl = new Uri("http://localhost:5678/DemoService/metadata"); host.Description.Behaviors.Add(b); host.Opened += delegate { label1.Text = "服务启动"; }; host.Open(); 比原来多了4行添加服务行为的代码。 现在,运行两个宿主程序中的任意一个,点击启动按钮后,服务就启动并发布了,客户端可以发现契约并使用。   客户端: 客户端如何发现并使用服务,有2种方式:使用命令行svcutil生成文件、在IDE中添加服务引用。 1、使用svcutil 运行宿主并启动服务;运行Visual Studio 命令提示,键入svcutil http://localhost:5678/DemoService/metadata,将生成一个DemoService.cs文件和一个output.config文件(可以通过/out:指定输出目录); 在解决方案中添加一个Windows窗体应用程序WCFDemo.Client,为其添加引用System.ServiceModel和System.Runtime.Serialization; 将刚才生成的两个文件添加到项目,并将output.config改名为App.config; 在窗体上放置一个Button和DataGridView,为Button的Click编写代码如下: DemoServiceClient c = new DemoServiceClient(); dataGridView1.DataSource = c.GetMonitorData(); 当然可以不用配置文件,new DemoServiceClient()中设置参数binding和remoteAddress。 svcutil常用的选项有/out:、/config:、/noconfig:等,详细用法这里就不介绍了。查看配置文件会发现里面内容很多,因为它自动为关键的绑定节点设置了默认值,这部分内容可以删除,所以很多时候不使用svcutil生成的配置文件。 2、添加服务引用 右击WCFDemo.Client,在添加服务引用对话框中输入地址http://localhost:5678/DemoService/metadata,点击“前往”按钮: 给命名空间起个好名(示例中就用默认名)后确定。 我们会发现,除了添加了服务引用,还修改了配置文件,如果原来没有配置文件,添加服务引用后会自动添加配置文件。 在窗体上再放置一个Button,为其Click编写代码如下: ServiceReference1.DemoServiceClient c = new ServiceReference1.DemoServiceClient(); dataGridView1.DataSource = c.GetMonitorData(); 和前一个一样,可以不用配置文件。   服务器有两种方案发布自己的元数据:基于HTTP-GET协议、使用专门的终结点。以上介绍的是前一种,下面介绍一下第二种。 1、使用配置文件 将之前的WCFDemo.Host.WithConfig项目的配置文件用WCF服务配置编辑器打开,新建服务终结点,并设置ABC: 现在WCFDemo.Host.WithConfig已提供两种发布服务的方式,启动服务后,客户端通过之前的地址http://localhost:5678/DemoService/metadata和刚才输入的地址http://localhost:5678/DemoService/MEX,都可以找到服务。 2、使用代码方式 在WCFDemo.Host.WithoutConfig项目的启动服务代码处增加一行添加终结点代码: host = new ServiceHost(typeof(DemoService)); host.AddServiceEndpoint(typeof(IDemoService), new BasicHttpBinding(), "http://localhost:5678/DemoService"); ServiceMetadataBehavior b = new ServiceMetadataBehavior(); b.HttpGetEnabled = true; b.HttpGetUrl = new Uri("http://localhost:5678/DemoService/metadata"); host.Description.Behaviors.Add(b); host.AddServiceEndpoint(typeof(IMetadataExchange), new CustomBinding(new HttpTransportBindingElement()), "http://localhost:5678/DemoService/MEX"); host.Opened += delegate { label1.Text = "服务启动"; }; host.Open(); 效果同上。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服