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 服务支持的增强;对路由服务,工作流服务,字节流编码,非破坏性队列接收,服务发现的支持

 


介绍

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

化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 <%@ 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

化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 <?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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 <?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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 <?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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 <%@ 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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 /*

* 注意:

* 如果需要引用 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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 <?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 化零为整WCF(19) - WCF 4.0 新特性_.net化零为整WCF(19) - WCF 4.0 新特性_缓存_02代码 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