化零为整WCF(19) - WCF 4.0 新特性

[索引页]
[源码下载]


化零为整WCF(19) - WCF 4.0 新特性


作者: webabcd


介绍
WCF(Windows Communication Foundation) - WCF 4.0 新特性
  • 简化配置(Simplified configuration) - 根据 baseAddresses 生成默认 endpoint;在应用程序的级别上指定默认的 Binding 配置和 Behavior 配置
  • 不需要 .svc 的物理文件,而直接在 IIS 上托管 WCF 服务
  • 标准终结点(Standard Endpoint) - 内置了 8 个已经定义好相关配置的标准终结点(分别为 mexEndpoint, announcementEndpoint, discoveryEndpoint, udpAnnouncementEndpoint, udpDiscoveryEndpoint, workflowControlEndpoint, webHttpEndpoint, webScriptEndpoint)
  • 通过标准终结点中的 webScriptEndpoint 来提供 ajax 服务 
  • 对 REST 服务支持的增强 
  • 对路由服务,工作流服务,字节流编码,非破坏性队列接收,服务发现的支持 


示例
1、概述
Index.aspx
代码
<% @ Page Language = " C# "  AutoEventWireup = " true "  CodeBehind = " Index.aspx.cs "  Inherits = " WebClient.Index "   %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head  runat ="server" >
    
< title ></ title >
</ head >
< body >
    
< form  id ="form1"  runat ="server" >
    
< div >
        
< p >
            1、简化配置(Simplified configuration) - 根据 baseAddresses 生成默认 endpoint;在应用程序的级别上指定默认的 Binding 配置和 Behavior 配置
            
< br  />
            相关代码位置:host 端在 WinHost 项目,client 端在 WebClient 项目中的 SimplifiedConfiguration.aspx 页面
        
</ p >
        
< p >
            2、不需要 .svc 的物理文件,而直接在 IIS 上托管 WCF 服务
            
< br  />
            相关代码位置:host 端在 WebHost 项目中的 web.config 文件,client 端在 WebClient 项目中的 IIS_Hosting_Without_SVC_File.aspx 页面
        
</ p >
        
< p >
            3、标准终结点(Standard Endpoint) - 内置了 8 个已经定义好相关配置的标准终结点(分别为 mexEndpoint, announcementEndpoint, discoveryEndpoint, udpAnnouncementEndpoint, udpDiscoveryEndpoint, workflowControlEndpoint, webHttpEndpoint, webScriptEndpoint)
            
< br  />
            指定标准终结点的方法见 WebHost 项目中的 web.config 文件
        
</ p >
        
< p >
            4、通过标准终结点中的 webScriptEndpoint 来提供 ajax 服务
            
< br  />
            相关代码位置:host 端在 WebHost 项目中的 web.config 文件,client 端在 WebHost 项目中的 WebScriptEndpointDemo.aspx 页面
        
</ p >
        
< p >
            5、对 REST 服务支持的增强
            
< ul >
                
< li >
                    通过标准终结点 webHttpEndpoint 来简化配置(详见:WebHost 项目中的 web.config 文件)
                
</ li >
                
< li >
                    通过对 behavior 的配置来为 REST 服务增加 help 页面,在服务地址上加“/help”即可进入 REST 服务的帮助页面(详见:WebHost 项目中的 web.config 文件)
                    
< br  />
                    本例的 REST 服务的帮助页面为 http://localhost:14802/RestDemo.svc/help
                
</ li >
                
< li >
                    为 REST 增加 HTTP 缓存配置(详见:WebHost 项目中的 web.config 文件,ServiceLib 项目的 RestDemo.cs 文件)
                
</ li >
            
</ ul >
        
</ p >
        
< p >
            6、路由服务(Routing Service) - WCF 对 Web Services Addressing (WS-Addressing) 规范的实现
        
</ p >
        
< p >
            7、工作流服务(Workflow Service) - WCF 对 WF (Workflow Foundation) 的支持
        
</ p >
        
< p >
            8、字节流编码(ByteStream) - 增加了对 ByteStream 的支持。原来只支持 Text, Binary, MTOM
        
</ p >
        
< p >
            9、非破坏性队列接收(Non-destructive queue receive) - 改进了原有的对 MSMQ(消息队列) 的支持
        
</ p >
        
< p >
            10、服务发现(WS-Discovery) - 对 WS-Discovery 协议的支持
        
</ p >
    
</ div >
    
</ form >
</ body >
</ html >


2、简化配置(Simplified configuration)的 Demo
服务端:Demo.cs
代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

using  System.ServiceModel;

namespace  ServiceLib
{
    [ServiceContract]
    
public   interface  IDemo
    {
        [OperationContract]
        
string  Hello( string  name);
    }

    
public   class  Demo : IDemo
    {
        
public   string  Hello( string  name)
        {
            
return   " Hello:  "   +  name;
        }
    }
}

宿主:App.config
代码
<? xml version="1.0" ?>
< configuration >
    
< system.serviceModel >

        
<!--
            1、如果没有显示配置 endpoint,那么 WCF 会根据 baseAddresses 生成一个默认 endpoint
            2、如果显示配置了 endpoint,那么 WCF 在默认情况下不会根据 baseAddresses 生成默认 endpoint
            3、如果需要强制为每个 baseAddresses 生成默认 endpoint,那么只要调用 ServiceHost.AddDefaultEndpoints() 方法即可(即使显示地指定 endpoint 也会生成默认的 endpoint)
            
            本例生成的默认 endpoint 的配置如下:
            A: http://localhost:1122/
            B: basicHttpBinding
            C: ServiceLib.IDemo
        
-->
        
< services >
            
< service  name ="ServiceLib.Demo" >
                
< host >
                    
< baseAddresses >
                        
< add  baseAddress ="http://localhost:1122/" />
                    
</ baseAddresses >
                
</ host >
            
</ service >
        
</ services >

        
<!--
            根据协议类型,指定其所对应的默认 Binding
        
-->
        
< protocolMapping >
            
< add  scheme ="http"  binding ="basicHttpBinding" />
            
< add  scheme ="net.tcp"  binding ="netTcpBinding" />
            
< add  scheme ="net.pipe"  binding ="netNamedPipeBinding" />
            
< add  scheme ="net.msmq"  binding ="netMsmqBinding" />
        
</ protocolMapping >

        
<!--
            WCF 应用程序的默认 Behavior 配置
        
-->
        
< behaviors >
            
< serviceBehaviors >
                
< behavior >
                    
< serviceMetadata  httpGetEnabled ="true" />
                    
< serviceDebug  includeExceptionDetailInFaults ="true" />
                
</ behavior >
            
</ serviceBehaviors >
        
</ behaviors >

        
<!--
            WCF 应用程序的默认 Binding 配置
        
-->
        
< bindings >
            
< basicHttpBinding ></ basicHttpBinding >
            
< webHttpBinding ></ webHttpBinding >
            
< wsHttpBinding >
                
< binding >
                    
< security  mode ="Message" >
                        
< transport  clientCredentialType ="None" ></ transport >
                    
</ security >
                
</ binding >
            
</ wsHttpBinding >
        
</ bindings >
    
</ system.serviceModel >
    
< startup >
        
< supportedRuntime  version ="v4.0"  sku =".NETFramework,Version=v4.0" />
    
</ startup >
</ configuration >

宿主:Form1.cs
代码
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Linq;
using  System.Text;
using  System.Windows.Forms;

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

namespace  WinHost
{
    
public   partial   class  Form1 : Form
    {
        
public  Form1()
        {
            InitializeComponent();

            
this .Load  +=   new  EventHandler(Form1_Load);
        }

        
void  Form1_Load( object  sender, EventArgs e)
        {
            ServiceHost host 
=   new  ServiceHost( typeof (ServiceLib.Demo));

            
//  强制为每个 baseAddresses 生成默认 endpoint(即使显示地指定 endpoint 也会生成默认的 endpoint)
            
//  host.AddDefaultEndpoints();

            
if  (host.State  !=  CommunicationState.Opening)
                host.Open();

            txtMsg.Text 
+=   string .Format( " endpoint 的数量: {0} " , host.Description.Endpoints.Count);
            txtMsg.Text 
+=   " \r\n " ;

            
foreach  (ServiceEndpoint se  in  host.Description.Endpoints)
            {
                txtMsg.Text 
+=   string .Format( " A: {0}\r\nB: {1}\r\nC: {2} " ,
                    se.Address, se.Binding.Name, se.Contract.Name);
            }
        }
    }
}


3、演示在没有 .svc 物理文件的情况下,直接在 IIS 上托管 WCF 服务
宿主的配置:Web.config
代码
<? xml version="1.0" ?>
< configuration >
    
< system.web >
        
< compilation  debug ="true"  targetFramework ="4.0"   />
    
</ system.web >
    
< system.serviceModel >

        
<!--
            要实现“不需要 .svc 的物理文件,而直接在 IIS 上托管 WCF 服务”的功能,需要指定相对地址和服务类型之间的映射关系
            relativeAddress - 向外提供服务的相对地址
            service - 服务类型
            factory - ajax 服务使用 System.ServiceModel.Activation.WebScriptServiceHostFactory , rest 服务使用 System.ServiceModel.Activation.WebServiceHostFactory
        
-->
        
< serviceHostingEnvironment >
            
< serviceActivations >
                
< add  relativeAddress ="IIS_Hosting_Without_SVC_File.svc"  service ="ServiceLib.Demo"   />
            
</ serviceActivations >
        
</ serviceHostingEnvironment >
        
        
< behaviors >
            
< serviceBehaviors >
                
< behavior >
                    
< serviceMetadata  httpGetEnabled ="true" />
                    
< serviceDebug  includeExceptionDetailInFaults ="true" />
                
</ behavior >
            
</ serviceBehaviors >
        
</ behaviors >
        
    
</ system.serviceModel >
</ configuration >


4、演示如何通过标准终结点中的 webScriptEndpoint 来提供 ajax 服务
服务端:AjaxDemo.cs
代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

using  System.ServiceModel;

namespace  ServiceLib
{
    [ServiceContract(Namespace 
=   " WCF " )]
    
public   interface  IAjaxDemo
    {
        [OperationContract]
        
string  Hello( string  name);
    }

    
public   class  AjaxDemo : IAjaxDemo
    {
        
public   string  Hello( string  name)
        {
            
return   " Hello:  "   +  name;
        }
    }
}

宿主的配置:Web.config
代码
<? xml version="1.0" ?>
< configuration >
    
< system.web >
        
< compilation  debug ="true"  targetFramework ="4.0"   />
    
</ system.web >
    
< system.serviceModel >

        
< serviceHostingEnvironment >
            
< serviceActivations >
                
< add  relativeAddress ="WebScriptEndpointDemo.svc"  service ="ServiceLib.AjaxDemo"  factory ="System.ServiceModel.Activation.WebScriptServiceHostFactory"   />
            
</ serviceActivations >
        
</ serviceHostingEnvironment >

        
<!--
            标准终结点是已经定义好相关配置的标准终结点
            通过 kind 指定标准终结点
        
-->
        
< services >
            
< service  name ="ServiceLib.AjaxDemo" >
                
< endpoint  kind ="webScriptEndpoint"  contract ="ServiceLib.IAjaxDemo"   />
            
</ service >
        
</ services >
        
        
< behaviors >
            
< serviceBehaviors >
                
< behavior >
                    
< serviceMetadata  httpGetEnabled ="true" />
                    
< serviceDebug  includeExceptionDetailInFaults ="true" />
                
</ behavior >
            
</ serviceBehaviors >
        
</ behaviors >
        
    
</ system.serviceModel >
</ configuration >

客户端:WebScriptEndpointDemo.aspx
代码
<% @ Page Language = " C# "  AutoEventWireup = " true "  CodeBehind = " WebScriptEndpointDemo.aspx.cs "
    Inherits
= " WebHost.WebScriptEndpointDemo "   %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head  runat ="server" >
    
< title ></ title >
</ head >
< body >
    
< form  id ="form1"  runat ="server" >
    
< div >
        
<!--
            因为 ajax 要同域,所以此 ajax 演示的 client 端要和 host 端在一起
        
-->

        
< asp:ScriptManager  ID ="ScriptManager1"  runat ="server" >
            
< Services >
                
< asp:ServiceReference  Path ="WebScriptEndpointDemo.svc"   />
            
</ Services >
        
</ asp:ScriptManager >

        
< script  type ="text/javascript" >

            
function  pageLoad() {
                
var  proxy  =   new  WCF.IAjaxDemo();
                proxy.Hello(
" webabcd " , onSuccess, onFailed);
            }

            
function  onSuccess(result) {
                alert(result);
            }

            
function  onFailed(error) {
                alert(error.get_message());
            }

        
</ script >
    
</ div >
    
</ form >
</ body >
</ html >


5、REST 服务的增强
服务端:RestDemo.cs
代码
/*
 * 注意:
 * 如果需要引用 System.ServiceModel.Web 程序集的话,需要把程序的目标框架设置为 .NET Framework 4 而不是默认的 .NET Framework 4 Client Profile(精简版)
 * 引用了目标框架为 .NET Framework 4 的项目的程序的目标框架也应该是 .NET Framework 4
 
*/

/*
 * 要在 REST 服务上实现 HTTP 缓存,需要做的配置如下
 * 1、在 web.config 中的 system.web/caching 节点上为 REST 服务提供一个缓存配置
 * 2、在方法上通过类似 [AspNetCacheProfile("Cache30S")] 的声明指定方法所使用的缓存配置
 * 3、在 web.config 中的 system.serviceModel/serviceHostingEnvironment 节点上增加一个属性 aspNetCompatibilityEnabled="true" ,以启用 asp.net 兼容模式
 * 4、在方法上使用如下声明,[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] ,以启用 asp.net 兼容模式
 
*/  

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

using  System.ServiceModel;
using  System.ServiceModel.Web;
using  System.ServiceModel.Activation;

namespace  ServiceLib
{
    [ServiceContract]
    
public   interface  IRestDemo
    {
        [OperationContract]
        [WebGet(UriTemplate 
=   " Hello/{name} " , ResponseFormat  =  WebMessageFormat.Json)]
        [AspNetCacheProfile(
" Cache30S " )]
        
string  Hello( string  name);
    }

    [AspNetCompatibilityRequirements(RequirementsMode 
=  AspNetCompatibilityRequirementsMode.Allowed)]
    
public   class  RestDemo : IRestDemo
    {
        
public   string  Hello( string  name)
        {
            
return   " Hello:  "   +  name  +   "  -  "   +  DateTime.Now.ToString( " yyyy-MM-dd HH:mm:ss " );
        }
    }
}

宿主端的配置:Web.config
代码
<? xml version="1.0" ?>
< configuration >
    
< system.web >
        
< compilation  debug ="true"  targetFramework ="4.0"   />

        
<!--
            要在 REST 服务上实现 HTTP 缓存,需要做的配置如下
            1、在 web.config 中的 system.web/caching 节点上为 REST 服务提供一个缓存配置
            2、在方法上通过类似 [AspNetCacheProfile("Cache30S")] 的声明指定方法所使用的缓存配置
            3、在 web.config 中的 system.serviceModel/serviceHostingEnvironment 节点上增加一个属性 aspNetCompatibilityEnabled="true" ,以启用 asp.net 兼容模式
            4、在方法上使用如下声明,[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] ,以启用 asp.net 兼容模式
        
-->
        
< caching >
            
< outputCacheSettings >
                
< outputCacheProfiles >
                    
< add  name ="Cache30S"  duration ="30"  varyByParam ="*"   />
                
</ outputCacheProfiles >
            
</ outputCacheSettings >
        
</ caching >
        
    
</ system.web >
    
< system.serviceModel >

        
< serviceHostingEnvironment  aspNetCompatibilityEnabled ="true" >
            
< serviceActivations >
                
< add  relativeAddress ="RestDemo.svc"  service ="ServiceLib.RestDemo"  factory ="System.ServiceModel.Activation.WebServiceHostFactory"   />
            
</ serviceActivations >
        
</ serviceHostingEnvironment >

        
<!--
            标准终结点是已经定义好相关配置的标准终结点
            通过 kind 指定标准终结点
        
-->
        
< services >
            
< service  name ="ServiceLib.RestDemo" >
                
< endpoint  kind ="webHttpEndpoint"  contract ="ServiceLib.IRestDemo"  behaviorConfiguration ="HelpBehavior"   />
            
</ service >
        
</ services >
        
        
< behaviors >
            
< endpointBehaviors >
                
<!--
                    启用 REST 的 Help 功能(在服务地址上加“/help”即可进入 REST 服务的帮助页面)
                    本例的 REST 服务的帮助页面为 http://localhost:14802/RestDemo.svc/help
                
-->
                
< behavior  name ="HelpBehavior" >
                    
< webHttp  helpEnabled ="true"   />
                
</ behavior >
            
</ endpointBehaviors >
            
< serviceBehaviors >
                
< behavior >
                    
< serviceMetadata  httpGetEnabled ="true" />
                    
< serviceDebug  includeExceptionDetailInFaults ="true" />
                
</ behavior >
            
</ serviceBehaviors >
        
</ behaviors >
        
    
</ system.serviceModel >
</ configuration >

客户端:RestDemo.aspx.cs
代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;
using  System.Web.UI;
using  System.Web.UI.WebControls;

using  System.Net;

namespace  WebClient
{
    
public   partial   class  RestDemo : System.Web.UI.Page
    {
        
protected   void  Page_Load( object  sender, EventArgs e)
        {
            System.Net.WebClient client 
=   new  System.Net.WebClient();

            var jsonResult 
=  client.DownloadString( " http://localhost:14802/RestDemo.svc/Hello/webabcd " );

            Response.Write(jsonResult);
        }
    }
}


OK
[源码下载]

你可能感兴趣的:(WCF)