您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
WCF基础(上)
 
作者:gameWYD 来源:CSDN 发布于:2015-12-17
  1751  次浏览      15
 

WCF(一) Windows Communication Foundation 概述

WCF被推出来很久了,但是对于刚刚接触WCF的人们来说,想必会有以下问题:

WCF是什么?为什么我们需要WCF?WCF能给我们带来什么?学习WCF的难易度如何?

以上这些问题的答案在网上已经很多介绍了,我在此本不必再浪费口舌,只是大概提一下。

WCF: Windows Communication Foundation.从名字可以看出,这是一项和通信密切相关的技术。我们知道软件设计到处是通信。当然我们必须学了以后,才能更好的知道它、运用它,而不能单单从它的名字揣测它的威力如何。

WCF提供给了我们一种面向服务(SOA)的程序设计的解决方案:何为面向服务?之前有使用过.NET Web Service 开发的朋友,很容易理解面向服务是咋回事。.Net Web Service也是更早的时候微软提出的一种面向服务的解决方案。面向服务是一种标准,不同的公司可以给出各自的实现框架。单纯的讲SOA,毕竟太抽象了。学习一下SOA的一种实现比如.Net Web Service 或WCF以后,相信不用任何文字定义,你也会深刻地理解SOA。所以,何为面向服务?这里不解释,等你学一段时间的WCF,你自己就有答案了,真的,呵呵。

WCF提供了统一的通信模型:以前我们写通信可以是:TCP/UDP,Socket等这些方式,在WCF中被统一了。至于如何统一?这里先不说了。所以,当你在项目中同时使用了多种通信方式时,可以考虑使用WCF了。

以前没有接触过Web Service 开发接受WCF也不是难事,相信我!

这次,我们只做一点WCF的概述,更为详细的知识到后面再慢慢展开。边学习,边交流。

1. 打开VS 2010 -->file-->new Project ,选择C#下面的WCF,选择WCF Library。如下图:

2.此时有了IService 文件和一个Service 文件。Service文件实现的IService中的两个函数:GetData函数和GetDataUsingDataContract函数。至于这两个函数是干嘛的?想必不用说大家都能看懂的。之后详细说明他们的角色。这里也不修改类名和函数名了,方面起见。

3.按F5运行程序,此时打开了一个WCF 的一个测试 窗口。如下图:先测试GetData函数

测试结果:

同样的方法测试GetDataUsingDataContract函数:结果如下图

4.上面完成了对WCF的函数功能的简单测试,能说明的是Service正确地实现了IService。接下来我们需要将这个WCF部署到一个Web Site中。

在解决方案上面右击:New -->New Web Site 如下图:

修改web site项目中的Service.svc 文件里面的 Service="WcfFirstDemoServiceLib.Service1" (其中意思就是已命名空间加类名的方式指定service的名字)

5.添加一个winForm程序 ,用它来调用WCF的函数。

6.给winForm 项目添加web 引用:

7.在Form1上面添加几个控件,然后再在Form1.cs中添加下列几行代码:

Form1.cs

8.Ctrl+F5 运行:

说明:这里只是概述WCF,所以全部在使用WCF的默认设置,也没有详细说明每一步的作用是什么。只是给出三个项目:项目1是WCF的库也是WCF功能核心。项目2是WCF的host用于向外界发布WCF提供的接口(注:接口这里指提供了哪些函数可被调用)。项目3是WCF的客户端用于调用WCF。其实,这里已经隐约体现出一点点分布式软件架构的意思了:有专门提供功能实现的模块,有专门提供对外公开接口的模块,有专门作为调用的模块。

后面详细WCF每一部分的。欢迎关注!!

WCF(二) Contract

上篇只是介绍了WCF的概述。具体的设置全是使用默认,这当然不可能满足我们开发的需要。如果仔细理一理的话,你会发现WCF里面的设置其实不算多的(与SharePoint比较的话)。从这篇开始,我们一点一点来展开学习。这次先提最最常用的Contract。

Contract有人翻译为:协定,契约。

WCF中有四种contract: 分别是:1.Service Contract. 2.Data Contract. 3. Fault Contract. 4.Message Contract.

还拿上篇中的例子(其实就是有Visual Studio2010替我们默认生成的代码了)说事:

1.Service Contract共分为两个部分:定义部分和实现部分。

 [ServiceContract]
2 public interface IService1
3 {
4 [OperationContract]
5 string GetData(int value);
6
7 [OperationContract]
8 CompositeType GetDataUsingDataContract(CompositeType composite);
9
10 }

这里IService就是一个service contract的定义部分,指定了哪些函数(Operation)向外公开(即:可供Client调用)。被[OperationContract]修饰的函数可以被客户端(Client)调用。

public class Service1 : IService1
2 {
3 public string GetData(int value)
4 {
5 return string.Format("You entered: {0}", value);
6 }
7
8 public CompositeType GetDataUsingDataContract(CompositeType composite)
9 {
10 if (composite == null)
11 {
12 throw new ArgumentNullException("composite");
13 }
14 if (composite.BoolValue)
15 {
16 composite.StringValue += "Suffix";
17 }
18 return composite;
19 }
20 }

Service1实现了IService接口,是Service Contract 的实现部分。VS自动生成的代码太简单了,不解释了。这里为了尽可能简单地说明问题。具体项目中,你可能需要连接数据库增、删、改、查数据,或对数据按n多复杂的业务规则进行数据处理以后,返回给client,等。
[ServiceContract] Attribute 可以有以下Property 的:

[OperationContract] Attribute 可以有以下Property 的:

Action	对请求设置WS-Addressing 的action
AsynchPattern 异步模式
HasProtectionLevel 消息是否加密,签名
IsInitiating 表明该函数被调用开始时是否要在server上面初始化一个session
IsOneWay 表明函数被client调用以后,client是否会等待函数返回
IsTerminating 表明该函数被调用结束时是否要在server上面关闭session
Name 设置函数的名字,在client端可见的名字,默认就是函数名字
ProtectionLevel
ReplyAction 设置函数返回消息的SOAP action

1.1 我们修改一下Service的默认命名空间,使他更make scene(有意义).

打开上篇中的解决方案WcfFirstDemo.sln

右键WebHost项目下面的文件:Service.svc,如下图:

点击连接如图:

得到如图效果:

 

默认Namespace是http://tempuri.org/

微软官方建议:修改Service的Namespace,使其包含:公司域名+项目名+版本号(如:日期表示版本号)

修改项目:WcfFirstDemoServiceLib下面的IService.cs代码如下:

[ServiceContract(Namespace="http://wwww.cnblogs.com/WCF/2012/07/28")]
2 public interface IService1
3 {
4 [OperationContract]
5 string GetData(int value);
6
7 [OperationContract]
8 CompositeType GetDataUsingDataContract(CompositeType composite);
9
10 }

右键项目WcfFirstDemoServiceLib 选择重新编译,成功以后,重新用浏览器打开service.svc,得到如下图:

此时已经改变了Service默认的Namespace了,client端需要更新一下,否则运行client端是会报异常的.操作如下图:

1.2修改Service的Name.默认情况下定义service的接口部分(如本例:IService)的名字就是Service的名字.但有时需要让client看到的service的名字跟server端看到的的service名字不一样.

我们先看一下WCFClient项目下面的app.config

修改WcfFirstDemoServiceLib项目下的IService.cs文件

[ServiceContract(Namespace="http://wwww.cnblogs.com/WCF/2012/07/28",Name="DemoService")]
2 public interface IService1
3 {
4 [OperationContract(Name="GetAge")]
5 string GetData(int value);
6
7 [OperationContract]
8 CompositeType GetDataUsingDataContract(CompositeType composite);
9
10 }

重新编译WcfFirstDemoServiceLib项目.更新client端对service的引用.此时你会发现client端app.config文件前后发生了变化:

此时WCFClient所生成的代理类的名字也会变化,你需要修改WCFClient

DemoService proxy = null;
1 private void Form1_Load(object sender, EventArgs e)
2 {
3 proxy = new DemoServiceClient("BasicHttpBinding_DemoService");
4
5 }
1 private void btnGetData_Click(object sender, EventArgs e)
2 {
3 this.tbOutputBox.Text = proxy.GetAge(Convert.ToInt32(this.tbInputbox.Text));
4 }

注:上面代码中DemoService 对应server端IService接口;DemoServiceClient对应server端的Service类.

当client端的app.config文件中只包含一个endpoint时,可以直接用proxy=new DemoServiceClient()传空参数,当然也可以传这个endpoint的name进去;但是当app.config包含多个endpoint时必须把endpoint的name传进去才能new出proxy对象.

2.DataContract.

WCF的Server和client之间利用特定格式的Message(消息)进行通信的。但是我们使用的高级语言:不论在Server端还是在client端,我们处理的业务数据都被封装成了对象。所以想把server端的对象传送到client(或相反方向)时,我们必须有能力把这些对象转换成特定格式的message,到另一端接收到message后再把它转回成对象。C#的基础类型(如int,string,float,bool等)可以做到这一点。因为一旦确定了Server端或client所用的编程语言,就可以确定这些基础类型的内存占用情况(例如:一个Server端定义的int变量在C#中占用多大内存空间是已知的,那么client端即便使用的是其他语言也完全可以计算出该变量的内存占用情况)。可是我们自己定义的类型可是五花八门了(比如:server端定义的Person类new出的object到底占用多大内存空间,就算Server端与client端使用同一种语言,Client端是不知道的Person类的对象的内存占用情况的。)

遇到这种请款下,我们怎么办呢?这时就轮到[DataContract]露面了。

ServiceContract做的工作是指定service向client提供了哪些函数可供调用。DataContract做的工作就是指定在Server端与client端之间可以传送的数据。[DataContract]的作用就是指定当需要传送某个类(如:Person类)的对象时,将该对象转化成为XML.接受方接到XML以后,再按同样的方式还原成对象。

[DataContract]Attribute 标在class定义上面一行。[DataMember]Attribute标在Property定义上面一行,field不需要Attribute修饰。

[DataContract]
2 public class CompositeType
3 {
4 bool boolValue = true;
5 string stringValue = "Hello ";
6
7 [DataMember]
8 public bool BoolValue
9 {
10 get { return boolValue; }
11 set { boolValue = value; }
12 }
13
14 [DataMember]
15 public string StringValue
16 {
17 get { return stringValue; }
18 set { stringValue = value; }
19 }
20 }

[DataContract]Attribute 可以像[ServiceContract]一样设置Name和Namespace.

[DataMember] Attribute 可以有以下属性:

EmitDefaultValue	设置一个默认值
IsRequired 进行序列化/反序列化时该值一定不可为空值
Name Property的名字
Order 设置进行序列化/反序列化的顺序

2.1修改DataContract的默认namespace ,

[DataContract(Namespace = "http://wwww.cnblogs.com/WCF/2012/07/28", Name = "CompositeTypeDemo")]
2 public class CompositeType
3 {
4 bool boolValue = true;
5 string stringValue = "Hello ";
6
7 [DataMember(Name="GetBool")]
8 public bool BoolValue
9 {
10 get { return boolValue; }
11 set { boolValue = value; }
12 }
13
14 [DataMember(Name="GetString")]
15 public string StringValue
16 {
17 get { return stringValue; }
18 set { stringValue = value; }
19 }
20 }

这样在client端看到的类(class)名,函数名与server看到的就不相同.

3.Fault Contract.

在WCF中处理异常(Exception)的方法有些特殊.我们不能单从server处理exception,需要进一步将Exception从server传送到client. 在后面我们再单独讨论WCF的Exception处理.

4. Message Contract.

Message Contract与Data Contract都是作用在传送的对象(object)上面.

不同的是:

datacontract是将object序列化化为xml. 实现object的各个property与xml 文本中各个node(节点)的对应);

messagecontract将对象组装成message(指定Message的Header,body).实现的是object各个property与消息的各个元素的对应.

具体的深层区别于联系,以及使用场景,我还不懂,希望有朋友对着块比较懂的,可以交流一下.如果后面等我弄懂了的话,我再专门写博文交流.

WCF(三) Message pattern

   
1751 次浏览       15
 
相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
 
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
 
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
最新课程计划
信息架构建模(基于UML+EA)3-21[北京]
软件架构设计师 3-21[北京]
图数据库与知识图谱 3-25[北京]
业务架构设计 4-11[北京]
SysML和EA系统设计与建模 4-22[北京]
DoDAF规范、模型与实例 5-23[北京]

使用decj简化Web前端开发
Web开发框架形成之旅
更有效率的使用Visual Studio
MVP+WCF+三层结构搭建框架
ASP.NET运行机制浅析【图解】
编写更好的C#代码
10个Visual Studio开发调试技巧
更多...   

.NET框架与分布式应用架构设计
.NET & WPF & WCF应用开发
UML&.Net架构设计
COM组件开发
.Net应用开发
InstallShield

日照港 .NET Framework & WCF应用开发
神华信息 .NET单元测试
北京 .Net应用软件系统架构
台达电子 .NET程序设计与开发
赛门铁克 C#与.NET架构设计
广东核电 .Net应用系统架构
更多...