WCF 基础加开发介绍(转)

19 篇文章 0 订阅

WCF --- Windows Communiction Foundation,是一个Microsoft 推出已久的技术。已久有很多人写了不少关于WCF的文章,比如谈谈WCF系列 等,都是很好的文章。我只是想说一些基础的东西,然后写一个例子,让目前刚开始学习WCF的人有一个感性的了解,希望能给他们的学习带来一点用处,同时是自己对WCF认识加深的一个过程。

WCF是一个统一的,可用于建立安全,可靠的面向服务的应用高效的开发平台 。WCF是构建安全可靠的事务性服务的统一框架 。它是一种构建分布式面向服务系统的非常丰富的技术基础 ,它统一了消息风格和RPC[Remote Procedure Call]风格,并且通过二进制和基于开放标准的通信达到了平台最优化。

它整合了.Net平台下所有的和分布式系统有关的技术,例如ASP.NET Web服务(ASMX)、增强Web服务扩展(WSE)、.Net Remoting、企业服务(Enterprise Service)和微软消息队列(MSMQ)。

而要理解WCF,你首先要理解WCF基本的组成部分,分别为:

  • Message  --- Soap Message, WCF不仅支持XML格式,而且还支持更加高效的Binary格式
    • Header   --- Message的Header,通常是附属信息,可以零个或多个
    • Body  --- Message的Body,通常是主题信息,可以零个或多个
  • Channel  --- 传输Message的通常,可以建立多个Channel,通常包括下面四部分信息,但一般不用我们指定,而是在配置Service/Endpoint中指定
    • Security  --- 传输安全性
      • Message Securty  --- Message的安全性,通常验证方式有Windows Authentication 或 X.509 或 Custom
        • Authentication  --- 验证
        • Integrity  --- 消息完整性
        • Confidentiality  --- 消息机密性,加密解密
        • Auditing  --- 审核
      • Transport Security  --- Transport的安全性
        • Https  --- 针对Http来说的安全传输
        • Other
    • Interoperability  --- 交互性,我的理解是,可以替代的服务类型
      • WebService
      • WSE
      • .Net Remoting
      • Enterprise Service
      • MSMQ
      • Other
    • Message pattern  --- Message的传输方式
      • Simplex  --- 单向传输,如A-->B
      • Duplex  --- 双向传输,如A<---->B,A先发送信息到B,B返回一个状态,然后A再发Message,然后B Response
      • Request-Respose  --- 要求/回复,A-->B,B-->A
    • Transport  --- 传输类型,Message是通过什么形式传输的
      • Http --- 无需保存连接状态
      • Tcp --- 需要保存连接状态,在Exchange Data的时候,会维护一个State
      • MSMQ  --- 通常用于需要可靠的Message传输的时候
      • Named Pipes  --- 通常用于单个PC的不同进程间通信
  • Service
    • Service
      • Contract  --- 契约
        • Data Contract  --- 数据契约,告诉程序该数据可以用于WCF传输,通常用来指定我们自定义的Model对象,是serializable的一种类型,命名空间为System.Runtime.Serialize。
        • Service Contract  --- 服务契约,告诉程序这是该一个WCF服务
        • Operation Contract  --- 操作契约,告诉程序,这是该Service对外暴露的可以执行的操作
      • Implementation  --- Operation Contract的具体实现
    • Endpoint --- 在外界看来,服务的连接接地址
      • Address  --- 服务的具体地址,根据Transport类型,可以是Http,Tcp等
      • Binding  --- 下面的图标是Binding的不同类型
      •   image
      • Contract  --- 对外暴露的接口
    • Behavior  --- Service在执行时,要执行的一个行为,比如安全验证
      • Throttling  --- 决定同一时间一个Service可以使用的Thread数量、Service的实例数,传递的Message数量
      • Security  --- 决定Service的安全特性
      • Instancing  --- 决定Service实现类的可以创建的实例数
        • PerCall  --- 客户端的每次Request都会产生一个InstanceContext
        • PerSession  --- 根据每个客户端的Session来产生一个InstanceContext,并且和这个Session有相同的生命周期
        • Single  --- 单例模式
      • Error Handling  --- 但Service遇到异常并且需要返回信息时的处理方式
      • Concurrency  --- 控制一个InstanceContext可以跨多少个线程
        • Multiple  --- 可以跨多个线程
        • Single  --- 只能在单行程内执行
        • Reentrant  --- Each instance of the service can only process messages one at a time but can accept re-entrant operation calls
      • Transactions  ---  决定Service是否可以接受并执行来自客户端的事务.注意事务是客户端创建的,因此事务的完成与否由客户端决定,当然生命周期也是如此。
      • Custom  --- 自定义行为
    • Host  --- WCF的寄宿主,即运行Service的地方
      • Console Application
      • Web Application
      • WinForms Application
      • IIS
      • Service

image

下面我做一个简单实例来说明一下,一个WCF的开发,调用过程。

一,首先我们创建一个Console Application,叫做WCFDemo

image

二,我们既然要开发WCF,当然要引入一个WCF Service Application了,叫做Service,如果你不想创建单独的项目,你可以在别的项目中添加WCF Service的Item。在创建WCF Project的时候会自动生成IService和Service.svc,通常IService这个Service Contract我们是不会要的,因为调用Service的Client也需要用,所以我们会把他们放到统一的地方,本例中是叫Interface的项 目。单纯的Service.svc是很简单的一个实现了IService接口的一个类,没有什么特别之处,

   1:  
namespace
 Service
   2:  
{
   3:  
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
   4:  
    public
 class
 Service : IService
   5:  
    {
   6:  
        public
 Computer GetComputer()
   7:  
        {
   8:  
            Computer computer = new
 Computer();
   9:  
            computer.ComputerName = "Ralax - PC"
;
  10:  
            return
 computer;
  11:  
        }
  12:  
    }
  13:  
}
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

而一个值得我们注意的地方就是,如果我们的Service名称变换了,一定要记得在Service.svc的Markup的CodeBehind修改引用,

   1:  
<%@ ServiceHost Language="C#"
 Debug="true"
 Service="Service.Service"
 CodeBehind="Service.svc.cs"
 %>

而作为Service的Config,应该是很重要的一个地方了,Config是配置Service如何运行,如何访问等的很重要的地方。如下:

   1:  
  <system.serviceModel>
   2:  
    <services>
   3:  
      <service name="Service.Service"
 behaviorConfiguration="Service.ServiceBehavior"
>
   4:  
        <!-- Service Endpoints -->
   5:  
        <endpoint address=""
 binding="wsHttpBinding"
 contract="Interface.IService"
>
   6:  
          <!-- 
   7:  
              Upon deployment, the following identity element should be removed or replaced to reflect the 
   8:  
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
   9:  
              automatically.
  10:  
          -->
  11:  
          <identity>
  12:  
            <dns value
="localhost"
/>
  13:  
          </identity>
  14:  
        </endpoint>
  15:  
        <endpoint address="mex"
 binding="mexHttpBinding"
 contract="IMetadataExchange"
/>
  16:  
      </service>
  17:  
    </services>
  18:  
    <behaviors>
  19:  
      <serviceBehaviors>
  20:  
        <behavior name="Service.ServiceBehavior"
>
  21:  
          <!-- To avoid disclosing metadata information, set the value
 below to false
 and remove the metadata endpoint above before deployment -->
  22:  
          <serviceMetadata httpGetEnabled="true"
/>
  23:  
          <!-- To receive exception details in
 faults for
 debugging purposes, set the value
 below to true
.  Set to false
 before deployment to avoid disclosing exception information -->
  24:  
          <serviceDebug includeExceptionDetailInFaults="true"
/>
  25:  
        </behavior>
  26:  
      </serviceBehaviors>
  27:  
    </behaviors>
  28:  
  </system.serviceModel>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

这里面很重要的部分,就是endpoint的配置ABC,address,binding和contract,另外还有bindingConfiguration,behavirorConfiguration等。

三,我刚才提到IService被提到Interface这个项目中,共Client和Service共同使用,其实IService更加简单,就 是一个加了ServiceContract的interface,和一些加了OperationContract的Methods。

   1:  
namespace
 Interface
   2:  
{ 
   3:  
    [ServiceContract]
   4:  
    public
 interface
 IService
   5:  
    {
   6:  
        [OperationContract]
   7:  
        Computer GetComputer();
   8:  
    }
   9:  
}
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

四,另外一个项目就是Data,这个项目是我们的Model类,加上了DataContract就可以就可以用于WCF传输,同时对于公开的Property,需要加上DataMember。

   1:  
namespace
 Data
   2:  
{
   3:  
    [DataContract]
   4:  
    public
 class
 Computer
   5:  
    {
   6:  
        private
 string
 computerName;
   7:  
        [DataMember]
   8:  
        public
 string
 ComputerName
   9:  
        {
  10:  
            get { return
 computerName; }
  11:  
            set { computerName = value
; }
  12:  
        }
  13:  
    }
  14:  
}

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

完成了上面的部分,也可以说一个Service也就完成了,剩下的就是客户端的调用了。

五,在Console Application中创建一个Service的客户端代理类,如下:

   1:  
namespace
 WCFDemo
   2:  
{
   3:  
    public
 class
 ServiceClient : ClientBase<IService>,IService
   4:  
    {
   5:  
        public
 ServiceClient(System.ServiceModel.Channels.Binding binding,EndpointAddress remoteAddress) : base
(binding,remoteAddress)
   6:  
        {
   7:  
            
   8:  
        }
   9:  
 
  10:  
        public
 Computer GetComputer()
  11:  
        {
  12:  
            return
 base
.Channel.GetComputer();
  13:  
        }
  14:  
    }
  15:  
}

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } 需要注意的是,ServiceClient继承关系,以及构造函数

ServiceClient完成后,就是Client的调用了,如下:

   1:  
namespace
 WCFDemo
   2:  
{
   3:  
    class
 Program
   4:  
    {
   5:  
        static
 void
 Main(string
[] args)
   6:  
        {
   7:  
            using
(ServiceClient sClient = GetService())
   8:  
            {
   9:  
                Console.WriteLine(sClient.GetComputer().ComputerName);
  10:  
                Console.Read();
  11:  
            }            
  12:  
        }
  13:  
 
  14:  
        public
 ServiceClient GetService()
  15:  
        {
  16:  
            WSHttpBinding binding = new
 WSHttpBinding();
  17:  
            EndpointAddress address = new
 EndpointAddress(new
 Uri("http://localhost/WCFDemo/Service.svc"
));
  18:  
            ServiceClient client = new
 ServiceClient(binding, address);
  19:  
            return
 client;
  20:  
        }
  21:  
    }
  22:  
}
 
这个例子,我已经打包了,可以在这里下载:http://files.cnblogs.com/myg2006/WCFDemo.rar


文章来自:http://www.cnblogs.com/myg2006/archive/2008/03/09/1097189.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值