• 化零为整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
    [源码下载]
  • 相关阅读:
    使用GO操作MongoDB
    解决golang时间字符串转time.Time的坑
    [Exercises on 2022.5.3] Dynamic Programming
    [Contest on 2022.5.13] 再这样熬夜我就要猝死了
    合成史莱姆
    [Contest on 2022.5.4] 痛啊!上周真的直接摆过去了!
    [Exercises on 2022.5.11] 字符串转风车煮饭吃蒸饭吃脂肪层
    [Contest on 2022.5.6] 手写 bitset 模板
    CodeForces 547E Mike and Friends
    [Contest on 2022.5.2] 端午节能放几天啊?
  • 原文地址:https://www.cnblogs.com/webabcd/p/1790175.html
Copyright © 2020-2023  润新知