﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-TerryLee's Tech Space</title><link>http://www.cnblogs.com/Terrylee/</link><description>TerryLee技术专栏</description><language>zh-cn</language><lastBuildDate>Fri, 05 Dec 2008 17:33:29 GMT</lastBuildDate><pubDate>Fri, 05 Dec 2008 17:33:29 GMT</pubDate><ttl>60</ttl><item><title>写在WinHEC开幕之际：沿着Windows我们一路走来</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 23 Nov 2008 10:59:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1339477.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html#Feedback</comments><slash:comments>29</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1339477.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1339477.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_winHEC.png" alt=""/></div>微软 2008 Windows 硬件工程大会（Windows Hardware Engineering Conference 2008，简称WinHEC 2008 China）即将于 2008年12月3-4日在北京万豪酒店盛大开幕，今年是微软第一次在中国独立举办WinHEC大会，以至于JesseQu用WinHEC终于来了一文回忆了自己近18年软件开发工作中对驱动、内核层次开发工作的情愫感慨。在WinHEC 2008开幕之际，让我们一起来回顾一下Windows的发展历史，寻找那些曾经熟悉的符号。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1339477.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43812/" target="_blank">[新闻]Google操作系统已开始内部测试？</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>使用微软分布式缓存服务Velocity Part 2</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 20 Nov 2008 16:00:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1338062.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html#Feedback</comments><slash:comments>53</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1338062.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1338062.html</trackback:ping><description><![CDATA[<h2>概述</h2> <p>Velocity是微软推出的分布式缓存解决方案，为开发可扩展性，可用的，高性能的应用程提供支持，可以缓存各种类型的数据，如CLR对象、XML、二进制数据等，并且支持集群模式的缓存服务器。Velocity也将集成在.NET Framework 4.0中，本文将介绍Velocity中的配置模型、缓存复杂数据和创建分区、使用标签以及ASP.NET SessionState提供者。  <h2>配置模型</h2> <p>在本文开始之前，先简单介绍一下Velocity中的配置模型，主要包括三方面的配置，缓存集群的配置，缓存宿主服务器配置以及应用程序的配置，如下图所示：  <p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="309" alt="Velocity_001" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart2_14B47/Velocity_001_3.png" width="580" border="0">  <p>缓存集群的配置，可以基于XML、SQL Server CE或者SQL Server数据库来进行存储，包括各个服务器以及所有的命名缓存、是否过期等配置，当我们使用Windows PowerShell管理工具进行配置时，将会修改该配置文件，如下代码所示：<pre class="code"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml </span><span style="color: red">version</span><span style="color: blue">=</span>"<span style="color: blue">1.0</span>" <span style="color: red">encoding</span><span style="color: blue">=</span>"<span style="color: blue">utf-8</span>"<span style="color: blue">?&gt;
&lt;</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">configSections</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">section </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">dcache</span>" <span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.DCacheSection, 
             CacheBaseLibrary, Version=1.0.0.0, Culture=neutral,
             PublicKeyToken=89845dcd8080cc91</span>" <span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">configSections</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">dcache </span><span style="color: red">cluster</span><span style="color: blue">=</span>"<span style="color: blue">localhost</span>" <span style="color: red">size</span><span style="color: blue">=</span>"<span style="color: blue">Small</span>"<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">caches</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">cache </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">partitioned</span>" <span style="color: red">consistency</span><span style="color: blue">=</span>"<span style="color: blue">strong</span>" <span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"<span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">policy</span><span style="color: blue">&gt;
          &lt;</span><span style="color: #a31515">eviction </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">lru</span>" <span style="color: blue">/&gt;
          &lt;</span><span style="color: #a31515">expiration </span><span style="color: red">defaultTTL</span><span style="color: blue">=</span>"<span style="color: blue">10</span>" <span style="color: red">isExpirable</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: blue">/&gt;
        &lt;/</span><span style="color: #a31515">policy</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">cache</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">cache </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">partitioned</span>" <span style="color: red">consistency</span><span style="color: blue">=</span>"<span style="color: blue">strong</span>" <span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">other</span>"<span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">policy</span><span style="color: blue">&gt;
          &lt;</span><span style="color: #a31515">eviction </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">lru</span>" <span style="color: blue">/&gt;
          &lt;</span><span style="color: #a31515">expiration </span><span style="color: red">defaultTTL</span><span style="color: blue">=</span>"<span style="color: blue">10</span>" <span style="color: red">isExpirable</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: blue">/&gt;
        &lt;/</span><span style="color: #a31515">policy</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">cache</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">caches</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">host </span><span style="color: red">clusterPort</span><span style="color: blue">=</span>"<span style="color: blue">22234</span>" <span style="color: red">hostId</span><span style="color: blue">=</span>"<span style="color: blue">1319514812</span>" <span style="color: red">size</span><span style="color: blue">=</span>"<span style="color: blue">1024</span>" <span style="color: red">quorumHost</span><span style="color: blue">=</span>"<span style="color: blue">true</span>"
          <span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">TERRYLEE-PC</span>" <span style="color: red">cacheHostName</span><span style="color: blue">=</span>"<span style="color: blue">DistributedCacheService</span>"
          <span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>" <span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">advancedProperties</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">partitionStoreConnectionSettings </span><span style="color: red">providerName</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.SqlServerCe.3.5</span>"
          <span style="color: red">connectionString</span><span style="color: blue">=</span>"<span style="color: blue">D:\CacheShare\ConfigStore.sdf</span>" <span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">advancedProperties</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">dcache</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>
<p>在上一篇的示例中，并没有使用应用程序配置文件，事实上使用配置文件是更好的编程实践，首先需要添加一个配置区：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">section </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">dcacheClient</span>"
<span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.DCacheSection, 
      CacheBaseLibrary, Version=1.0.0.0, 
      Culture=neutral, PublicKeyToken=89845dcd8080cc91</span>"<span style="color: blue">/&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>配置信息包括部署方式，是否启用本地缓存以及缓存宿主等，如下代码所示：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">localCache </span><span style="color: red">isEnabled</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: red">sync</span><span style="color: blue">=</span>"<span style="color: blue">TTLBased</span>" <span style="color: red">ttlValue</span><span style="color: blue">=</span>"<span style="color: blue">300</span>" <span style="color: blue">/&gt;
  &lt;</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">host </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">localhost</span>" <span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>" 
          <span style="color: red">cacheHostName</span><span style="color: blue">=</span>"<span style="color: blue">DistributedCacheService</span>"<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>
<p>现在Velocity CTP2对于应用程序使用配置的支持似乎有些问题。缓存宿主的配置放在DistributedCache.exe.config文件中，可以在Velocity安装目录下找到。 
<h2>缓存复杂数据类型</h2>
<p>在Velocity中，可以缓存任何类型的数据，如CLR对象、XML或者二进制数据等。现在看一个简单的示例，如何缓存复杂类型数据，定义一个如下的Customer类，注意要能够序列化：<pre class="code">[<span style="color: #2b91af">Serializable</span>]
<span style="color: blue">public class </span><span style="color: #2b91af">Customer
</span>{
    <span style="color: blue">public </span><span style="color: #2b91af">String </span>ID { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">public </span><span style="color: #2b91af">String </span>FirstName { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">public </span><span style="color: #2b91af">String </span>LastName { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">public int </span>Age { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }

    <span style="color: blue">public </span><span style="color: #2b91af">String </span>Email { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>对应用程序做配置，参考本文的配置模型部分，使用方法与简单数据类型的基本一致，如添加缓存项，使用Customer主键作为缓存键，其中GetCurrentCache()方法的实现请参考上一篇文章：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117002"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};

cache.Add(customer.ID, customer);</pre><a href="http://11011.net/software/vspaste"></a>
<p>获取缓存项：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">Customer </span>customer = cache.Get(<span style="color: #a31515">"C20081117002"</span>) <span style="color: blue">as </span><span style="color: #2b91af">Customer</span>;</pre><a href="http://11011.net/software/vspaste"></a>
<p>移除缓存项：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
cache.Remove(<span style="color: #a31515">"C20081117002"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>更新缓存中数据，可以有两种方法，一是直接使用缓存索引，如果确保缓存键存在：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117002"</span>,
    FirstName = <span style="color: #a31515">"Huijui"</span>,
    LastName = <span style="color: #a31515">"Li"</span>,
    Age = 26,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};
cache[<span style="color: #a31515">"C20081117002"</span>] = customer;</pre><a href="http://11011.net/software/vspaste"></a>
<p>另外一种是使用Put方法，如果缓存键不存在，它将会新增到缓存中，否则会进行覆盖，如下代码所示：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117002"</span>,
    FirstName = <span style="color: #a31515">"Huijui"</span>,
    LastName = <span style="color: #a31515">"Li"</span>,
    Age = 26,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};
cache.Put(customer.ID, customer);</pre><a href="http://11011.net/software/vspaste"></a>
<h2>使用分区</h2>
<p>在实际部署中，经常会出现多个应用程序共享同一个缓存集群，这不可避免的会出现缓存键冲突，如上面的示例中使用CustomerID作为缓存键，此时可以使用Velocity中的分区功能，它会在逻辑上把各个命名缓存再进行分区，这样可以完全保持数据隔离，如下图所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="387" alt="TerryLee_0216" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart2_14B47/TerryLee_0216_3.png" width="519" border="0"> 
<p>图中共有三个命名缓存，其中在缓存Catalog中又分区为Sports和Arts。在Velocity中对于分区的操作提供了如下三个方法，可以用于创建分区，删除分区以及清空分区中所有的对象：<pre class="code"><span style="color: blue">public void </span>ClearRegion(<span style="color: blue">string </span>region);
<span style="color: blue">public bool </span>CreateRegion(<span style="color: blue">string </span>region, <span style="color: blue">bool </span>evictable);
<span style="color: blue">public bool </span>RemoveRegion(<span style="color: blue">string </span>region);</pre><a href="http://11011.net/software/vspaste"></a>
<p>如下代码所示，创建了一个名为“Customers”的分区，在调用Add方法时可以指定数据将会缓存到哪个分区：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: blue">string </span>regionName = <span style="color: #a31515">"Customers"</span>;
cache.CreateRegion(regionName, <span style="color: blue">false</span>);

<span style="color: #2b91af">Customer </span>customer = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117003"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};

cache.Add(regionName, customer.ID, customer);</pre><a href="http://11011.net/software/vspaste"></a>
<p>可以使用Get-CacheRegion命令在Windows PowerShell中来查看一下当前缓存集群中所有的分区信息，如下图所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="222" alt="Velocity_002" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart2_14B47/Velocity_002_3.png" width="580" border="0"> 
<p>同样在检索缓存数据时，仍然可以使用分区名进行检索。 
<h2>使用标签</h2>
<p>在Velocity还允许对加入到缓存中的缓存项设置Tag，可以是一个或者多个，使用了Tag，就可以从多个方面对缓存项进行描述，这样在检索数据时，就可以根据Tag来一次检索多个缓存项。为缓存项设置Tag，如下代码所示：<pre class="code"><span style="color: #2b91af">Cache </span>cache = GetCurrentCache();
<span style="color: blue">string </span>regionName = <span style="color: #a31515">"Customers"</span>;

<span style="color: #2b91af">Customer </span>customer1 = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117004"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};
<span style="color: #2b91af">Customer </span>customer2 = <span style="color: blue">new </span><span style="color: #2b91af">Customer</span>()
{
    ID = <span style="color: #a31515">"C20081117005"</span>,
    FirstName = <span style="color: #a31515">"Terry"</span>,
    LastName = <span style="color: #a31515">"Lee"</span>,
    Age = 25,
    Email = <span style="color: #a31515">"lhj_cauc[#AT#]163.com"
</span>};

<span style="color: #2b91af">Tag </span>tag1 = <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>(<span style="color: #a31515">"Beijing"</span>);
<span style="color: #2b91af">Tag </span>tag2 = <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>(<span style="color: #a31515">"Tianjin"</span>);
cache.Add(regionName, customer1.ID, customer1, <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>[] { tag1, tag2 });
cache.Add(regionName, customer2.ID, customer2, <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>[] { tag2 });</pre><a href="http://11011.net/software/vspaste"></a>
<p>这样就可以对设置了Tag的缓存项进行检索，根据实际需求选择使用如下三个方法之一：<pre class="code">GetAllMatchingTags(<span style="color: blue">string </span>region, <span style="color: #2b91af">Tag</span>[] tags)
GetAnyMatchingTag(<span style="color: blue">string </span>region, <span style="color: #2b91af">Tag</span>[] tags)
GetByTag(<span style="color: blue">string </span>region, <span style="color: #2b91af">Tag </span>tag)</pre><a href="http://11011.net/software/vspaste"></a>
<p>第一个检索匹配所有Tag的数据，第二个检索匹配所有Tag中的任意一个即可，最后只使用一个Tag，如下代码所示：<pre class="code"><span style="color: blue">string </span>regionName = <span style="color: #a31515">"Customers"</span>;
<span style="color: #2b91af">Tag</span>[] tags = <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>[] { <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>(<span style="color: #a31515">"Beijing"</span>), 
           <span style="color: blue">new </span><span style="color: #2b91af">Tag</span>(<span style="color: #a31515">"Tianjin"</span>)};

<span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">KeyValuePair</span>&lt;<span style="color: blue">string</span>, <span style="color: blue">object</span>&gt;&gt; result
    = cache.GetAllMatchingTags(regionName, tags);</pre><a href="http://11011.net/software/vspaste"></a>
<p>使用Tag功能对于检索缓存项提供了极大的灵活性，对于任何一个数据，都可以使用多个Tag从很多方面去描述它。 
<h2>ASP.NET SessionState提供者</h2>
<p>Velocity还提供了对于ASP.NET SessionState提供者的支持，可以通过配置把Session信息缓存到缓存集群中，添加Velocity配置区：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">section </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">dcacheClient</span>"
         <span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.DCacheSection, 
         CacheBaseLibrary, Version=1.0.0.0, 
         Culture=neutral, PublicKeyToken=89845dcd8080cc91</span>"<span style="color: blue">/&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>配置缓存客户端信息：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">localCache </span><span style="color: red">isEnabled</span><span style="color: blue">=</span>"<span style="color: blue">true</span>" <span style="color: red">sync</span><span style="color: blue">=</span>"<span style="color: blue">TTLBased</span>" <span style="color: red">ttlValue</span><span style="color: blue">=</span>"<span style="color: blue">300</span>" <span style="color: blue">/&gt;
  &lt;</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">host </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">localhost</span>" <span style="color: red">cachePort</span><span style="color: blue">=</span>"<span style="color: blue">22233</span>" 
          <span style="color: red">cacheHostName</span><span style="color: blue">=</span>"<span style="color: blue">DistributedCacheService</span>"<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">hosts</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">dcacheClient</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a>
<p>配置SessionState信息：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">sessionState </span><span style="color: red">mode</span><span style="color: blue">=</span>"<span style="color: blue">Custom</span>" <span style="color: red">customProvider</span><span style="color: blue">=</span>"<span style="color: blue">Velocity</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">providers</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">add </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">Velocity</span>" 
         <span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">System.Data.Caching.SessionStoreProvider,ClientLibrary</span>"
         <span style="color: red">cacheName</span><span style="color: blue">=</span>"<span style="color: blue">default</span>"<span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">providers</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">sessionState</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>需要指定使用哪个命名缓存，但是该功能似乎到目前还存在问题，无法测试通过L 
<h2>总结</h2>
<p>本文简单介绍了Velocity的配置模型，以及如何缓存复杂数据类型，对命名缓存分区，为缓存项设置Tag，以及对于ASP.NET SessionState的支持，希望对大家有用。</p>
<p>相关文章：</p>
<p>1. <a href="http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html">使用微软分布式缓存服务Velocity Part 1</a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1338062.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43811/" target="_blank">[新闻]Google阅读器界面升级 全新改版</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>使用微软分布式缓存服务Velocity Part 1</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Wed, 19 Nov 2008 16:01:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1337121.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/20/Microsoft-Distributed-Cache-Velocity-Part1.html#Feedback</comments><slash:comments>76</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1337121.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1337121.html</trackback:ping><description><![CDATA[<h2>概述</h2> <p>Velocity是微软推出的分布式缓存解决方案，为开发可扩展性，可用的，高性能的应用程提供支持，可以缓存各种类型的数据，如CLR对象、XML、二进制数据等，并且支持集群模式的缓存服务器。Velocity也将集成在.NET Framework 4.0中，本文将介绍Velocity的一些预备知识、安装配置以及开发一个简单的示例。  <h2>简介</h2> <p>既然是分布式的缓存平台，客户端应用程序能够与缓存服务器集群中的任何一台服务器通信，并且执行缓存操作，如新增缓存项，移除缓存项等。在Velocity中，提供了一套统一的API，开发者可以使用任何一种.NET语言来访问这些API，如图1所示：  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="384" alt="TerryLee_0212" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0212_3.png" width="580" border="0">  <p>图 1 <h2>物理模型</h2> <p>在整个Velocity分布式缓存解决方案中，从物理模型上来看，主要涉及到如下几个元素：缓存宿主，缓存集群，Velocity提供的基于Windows PowerShell的管理工具，对于服务器集群配置的存储。缓存宿主是指一个或者多个以Windows服务形式运行的服务器，每台服务器都可以运行缓存宿主服务；缓存集群是一个或者多个缓存宿主实例的集合；当缓存集群启动时，它将从集群配置存储位置处来获取配置信息，Velocity提供了多种方式的集群配置信息存储，可以基于XML文件、SQL Server数据库或者SQL Server CE等；基于PowerShell的管理工具后面会详细讲到。 如图2所示：  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="365" alt="TerryLee_0213" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0213_3.png" width="564" border="0">&nbsp; <p>图 2 <h2>逻辑模型</h2> <p>从逻辑模型上来看，在Velocity中主要有命名缓存，在命名缓存中我们还可以继续分区，命名缓存，可以理解为内存中的一个独立的存储结构单元，它们之间完全互相隔离，互不干扰，当有多个应用程序共享同一个缓存集群时，可以为每个应用程序分别建立命名缓存；在同一个命名缓存中，还可以对命名缓存进行分区，这样即可以解决数据冲突的问题，再配合Velocity中的“标签”功能，可以极大的提高检索效率。如图3所示：  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="387" alt="TerryLee_0216" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0216_3.png" width="519" border="0">&nbsp;&nbsp; <p>图 3 <h2>安装</h2> <p>Velocity当前最新的版本是CTP 2，大家可以到微软官方站点下载，由于Velocity中提供了一套基于Windows PowerShell的管理工具，所以在安装之前需要首先安装Windows PowerShell。在安装过程中，其中有一步需要进行服务器集群的配置，如图4所示：  <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="415" alt="TerryLee_0214" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0214_3.png" width="544" border="0">  <p>图 4 <p>需要设置服务及集群端口号，集群配置的存储位置，集群配置存储的Provider，可以基于XML存储或者基于SQL Server CE存储等。另外可以访问如下站点获得一些资源：  <p>团队博客：<a href="http://blogs.msdn.com/velocity/">http://blogs.msdn.com/velocity/</a>&nbsp; <p>示例代码：<a href="http://code.msdn.microsoft.com/velocity">http://code.msdn.microsoft.com/velocity</a>  <p>安装完成后，请在Windows Service中启动Microsoft project code named "Velocity"服务。  <h2>管理工具</h2> <p>Velocity提供了基于Windows PowerShell的管理工具，对于Windows PowerShell不熟悉的可以参考《<b><a href="http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html">回归Dos操作的快感，进入PowerShell世界</a></b>》这篇文章。使用Windows PowerShell可以非常方便的对Velocity缓存集群、缓存宿主等进行管理。使用如下命令金额图对启动、停止、重启服务器集群： <pre class="code">Start-CacheCluster 
Stop-CacheCluster 
Restart-CacheCluster </pre><a href="http://11011.net/software/vspaste"></a>
<p>使用如下命令可以启动、停止缓存宿主、获取命名缓存、获取缓存分区等： <pre class="code">Get-CacheHost 
Get-CacheConfig 
Set-CacheConfig 
Start-CacheHost 
Stop-CacheHost 
Get-CacheStatistics 
Get-Cache 
Get-CacheRegion </pre><a href="http://11011.net/software/vspaste"></a>
<p>如使用Get-CacheHost命令获取缓存宿主的信息，如图5所示，可以看到宿主对应的服务名以及服务状态等： 
<p><img height="273" alt="TerryLee_0217" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0217_3.png" width="580" border="0"> 
<p>图 5
<p>使用Get-Cache命名查看所有的命名缓存，如图6所示： 
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="273" alt="TerryLee_0218" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0218_3.png" width="580" border="0"> 
<p>图 6
<p>使用该管理工具还可以创建、移除命名缓存等，这里不再叙述。 
<h2>简单示例</h2>
<p>经过前面一大堆的理论介绍，现在来看一个最简单的示例。首先要把CacheBaseLibrary和ClientLibrary这两个程序集添加到应用程中，在Velocity安装目录下可以找到，并且引入命名空间： <pre class="code"><span style="color: blue">using </span>System.Data.Caching;</pre><a href="http://11011.net/software/vspaste"></a>
<p>在使用Velocity缓存数据时，首先需要创建一个命名缓存，它可以通过CacheFactory来创建，如下代码所示： <pre class="code"><span style="color: blue">private </span><span style="color: #2b91af">Cache </span>GetCurrentCache()
{
    <span style="color: #2b91af">Cache </span>dCache;
    <span style="color: #2b91af">ServerEndPoint</span>[] servers = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>[1];
    servers[0] = <span style="color: blue">new </span><span style="color: #2b91af">ServerEndPoint</span>(<span style="color: #a31515">"localhost"</span>, 22233, <span style="color: #a31515">"DistributedCacheService"</span>);
    <span style="color: blue">bool </span>routingClient = <span style="color: blue">true</span>;
    <span style="color: blue">bool </span>localCache = <span style="color: blue">false</span>;
    <span style="color: blue">var </span>factory = <span style="color: blue">new </span><span style="color: #2b91af">CacheFactory</span>(servers, routingClient, localCache);
    dCache = factory.GetCache(<span style="color: #a31515">"default"</span>);

    <span style="color: blue">return </span>dCache;
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>此处首先指定了所有的服务器信息，当然这些都可以放在应用程序配置文件中，将会在下篇中介绍，有了Cache对象，其它的使用就非常方便了，如我们可以使用Add、Put、Remove、Get等方法来对缓存项进行操作， 
<p>添加缓存项： <pre class="code"><span style="color: #2b91af">Cache </span>dCache = GetCurrentCache();

<span style="color: #2b91af">String </span>key = keyTextbox.Text;
<span style="color: #2b91af">String </span>val = valueTxtBox.Text;

<span style="color: blue">if </span>(key == <span style="color: #a31515">"" </span>|| val == <span style="color: #a31515">""</span>) <span style="color: blue">return</span>;

dCache.Add(key, val);
statusLabel.Text =
    <span style="color: #2b91af">String</span>.Format(<span style="color: #a31515">"Successfully added key {0} to cache."</span>, key);</pre><a href="http://11011.net/software/vspaste"></a>
<p>获取缓存项： <pre class="code"><span style="color: #2b91af">Cache </span>dCache = GetCurrentCache();
<span style="color: #2b91af">String </span>key = keyTextbox.Text;

<span style="color: blue">if </span>(key == <span style="color: #a31515">""</span>) <span style="color: blue">return</span>;

<span style="color: #2b91af">String </span>val = dCache.Get(key).ToString();
valueTxtBox.Text = val;
statusLabel.Text =
    <span style="color: #2b91af">String</span>.Format(<span style="color: #a31515">"Successfully did Get of key {0} from cache"</span>, key);</pre><a href="http://11011.net/software/vspaste"></a>
<p>运行程序可以测试，数据被正确的缓存，如图7所示：
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="334" alt="TerryLee_0219" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/VelocityPart1_149E6/TerryLee_0219_3.png" width="472" border="0"> 
<p>图 7
<h2>总结</h2>
<p>本文简单介绍了微软的分布式缓存解决方案Velocity的一些概念以及开发了一个简单的示例，希望对大家有用。在下篇文章中，我们将会更深入学习缓存复杂数据类型以及Velocity的编程模型和配置模型。</p>
<p>相关文章：</p>
<p>1. <a href="http://www.cnblogs.com/Terrylee/archive/2008/11/21/Microsoft-Distributed-Cache-Velocity-Part2.html">使用微软分布式缓存服务Velocity Part 2 </a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1337121.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43810/" target="_blank">[新闻]微软官方下载：Windows Vista SP2 Beta测试版</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Silverlight 3一瞥</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/18/Silverlight-v3-Overview.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 17 Nov 2008 16:01:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/18/Silverlight-v3-Overview.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1335510.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/18/Silverlight-v3-Overview.html#Feedback</comments><slash:comments>64</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1335510.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1335510.html</trackback:ping><description><![CDATA[<p>今天<a href="http://weblogs.asp.net/scottgu/default.aspx">ScottGu</a>在自己的Blog上对目前正在开发中的Silverlight 3版本的新特性做了一些透露，Silverlight 3的新特性包括视频方面的增强，包括支持H.264 video；图形方面的增强包括3D支持和GPU硬件加速；开发方面的增强包括更加丰富的数据绑定支持和更多的控件。另外，从Silverlight 3起在开发工具方面也会有较大的改进，将会完全支持在Visual Studio或者Visual Web Developer Express中进行Silverlight应用程序的编写和交互设计（这点也是Silverlight 2在Visual Studio 2008中开发最为开发者诟病的一点），另外还会为数据绑定提供可视化工具，类似于ASP.NET中的数据绑定一样，如下图所示：</p> <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="418" alt="TerryLee_0211" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/Silverlight3_14F3D/TerryLee_0211_3.png" width="580" border="0">&nbsp;</p> <p>原文请参考：<a href="http://weblogs.asp.net/scottgu/archive/2008/11/16/update-on-silverlight-2-and-a-glimpse-of-silverlight-3.aspx">Update on Silverlight 2 - and a glimpse of Silverlight 3</a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1335510.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43809/" target="_blank">[新闻]微软发布PC Live单机游戏客户端</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（10）：消息处理功能核心</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/17/WCF-Messaging-Features-Core.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 17 Nov 2008 15:46:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/17/WCF-Messaging-Features-Core.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1335498.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/17/WCF-Messaging-Features-Core.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1335498.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1335498.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>WCF是一个通信框架，同时也可以将它看成是一个消息处理或者传递的基础框架，它可以接收消息、对消息做处理，或者根据客户端给定的数据构造消息并将消息发送到目标端点，在这个过程中，一切都是围绕“消息”而展开的。WCF在消息处理体系结构提供统一编程模型的同时，还允许灵活的表示数据和传递消息，本文将介绍如何配置消息支持各个SOAP和WS-Addressing版本或者不用任何SOAP和WS-Addressing，以及如何控制消息状态等。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/17/WCF-Messaging-Features-Core.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1335498.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43808/" target="_blank">[新闻]Firefox遭“独家”恶意软件攻击</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（9）：深度通道编程模型Part 2—实例篇</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/14/WCF-Channel-Programming-Model-Example.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 13 Nov 2008 16:22:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/14/WCF-Channel-Programming-Model-Example.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1333195.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/14/WCF-Channel-Programming-Model-Example.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1333195.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1333195.html</trackback:ping><description><![CDATA[<h2>引言</h2> <p>从本质上说，WCF是一个通信服务框架，它允许我们使用不同的传输协议，使用不同的消息编码形式，跟不同的WS-*系列规范交互，而所有这些细节都是由通道堆栈来处理的。在《<a href="http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html">WCF专题系列（8）：深度通道编程模型Part 1—设计篇</a>》中，对于WCF中的通道模型有了深入的认识，本文中，我将通过实例来说明在通道模型中，服务端是如何接收消息，客户端是如何发送消息的。  <h2>服务端通道</h2> <p>本文将不使用WCF的编程模型，而直接利用通道模型来进行通信，这样有助于我们更进一步加深对服务端处理消息的认识，在服务端侦听并接收消息的第一步需要创建绑定，我们既可以使用WCF中内置的绑定或者使用自定义的绑定，如下代码所示，创建一个CustomBinding：<pre class="code"><span style="color: green">// 创建自定义绑定
</span><span style="color: #2b91af">BindingElement</span>[] bindingElements = <span style="color: blue">new </span><span style="color: #2b91af">BindingElement</span>[2];
bindingElements[0] = <span style="color: blue">new </span><span style="color: #2b91af">TextMessageEncodingBindingElement</span>();
bindingElements[1] = <span style="color: blue">new </span><span style="color: #2b91af">HttpTransportBindingElement</span>();

<span style="color: #2b91af">CustomBinding </span>binding = <span style="color: blue">new </span><span style="color: #2b91af">CustomBinding</span>(bindingElements);</pre><a href="http://11011.net/software/vspaste"></a>
<p>此处添加了HttpTransportBindingElement，所以生成的通道堆栈具有HTTP传输通道，另外采用了文本消息编码器。接下来调用刚才创建的CustomBinding的BuildChannelListener方法来构造通道侦听器，需要指定侦听基地址以及绑定参数，另外调用Open()方法打开通道监听器，相信大家一定还记得Open()方法是在接口ICommunicationObject中定义的，如下代码所示：<pre class="code"><span style="color: green">// 使用自定义绑定创建通道侦听器         
</span><span style="color: #2b91af">IChannelListener</span>&lt;<span style="color: #2b91af">IReplyChannel</span>&gt; listener =
      binding.BuildChannelListener&lt;<span style="color: #2b91af">IReplyChannel</span>&gt;(
         <span style="color: blue">new </span><span style="color: #2b91af">Uri</span>(<span style="color: #a31515">"http://localhost:8887/StringService"</span>),
         <span style="color: blue">new </span><span style="color: #2b91af">BindingParameterCollection</span>());

<span style="color: green">// 监听消息
</span>listener.Open();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Listening for incoming channel connections"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>现在侦听传入的消息，由于我们使用请求了响应消息交换模式，此处侦听器返回一个实现了IReplyChannel的通道，为了在此通道上接收消息，我们首先对其调用Open()方法（该方法仍然是在ICommunicationObject中定义），以便将其置于一个准备进行通信的状态。 然后，我们调用ReceiveRequest()方法，它会处于阻止状态，直到消息达到，如下代码所示：<pre class="code"><span style="color: green">// 创建Reply通道
</span><span style="color: #2b91af">IReplyChannel </span>channel = listener.AcceptChannel();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Channel accepted. Listening for messages"</span>);
channel.Open();

<span style="color: #2b91af">RequestContext </span>request = channel.ReceiveRequest();</pre><a href="http://11011.net/software/vspaste"></a>
<p>当ReceiveRequest()方法返回一个RequestContext时，再使用其RequestMessage属性获取接收到的消息。输出消息的操作（Action）和内容。为了发送答复，在此例中创建一个新的答复消息，它会将我们在请求中接收到的字符串数据，添加一段字符后再传递回去。然后，调用Reply()方法以发送答复消息，如下代码所示：<pre class="code"><span style="color: green">// 读取请求的消息
</span><span style="color: #2b91af">Message </span>message = request.RequestMessage;
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Received"</span>);
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Action: {0}"</span>, message.Headers.Action);
<span style="color: blue">string </span>body = message.GetBody&lt;<span style="color: blue">string</span>&gt;();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Content: {0}"</span>, body);

<span style="color: green">// 发送响应消息
</span><span style="color: #2b91af">Message </span>replymessage = <span style="color: #2b91af">Message</span>.CreateMessage(
    binding.MessageVersion,
    <span style="color: #a31515">"http://www.cnblogs.com/TerryLee/Encode"</span>,
     <span style="color: #a31515">"Hello : " </span>+ body);

request.Reply(replymessage);</pre><a href="http://11011.net/software/vspaste"></a>
<p>最后别忘了做资源释放工作，关闭通道侦听器、通道、请求消息、请求上下文等，如下代码所示：<pre class="code"><span style="color: green">// 释放对象
</span>message.Close();
request.Close();
channel.Close();
listener.Close();</pre><a href="http://11011.net/software/vspaste"></a>
<p>完整的代码如下所示：<pre class="code"><span style="color: gray">/// &lt;summary&gt;
/// </span><span style="color: green">Author:TerryLee
</span><span style="color: gray">/// </span><span style="color: green">Url:http://www.cnblogs.com/terrylee
</span><span style="color: gray">/// &lt;/summary&gt;
</span><span style="color: blue">static void </span>Main()
{
    <span style="color: green">// 创建自定义绑定
    </span><span style="color: #2b91af">BindingElement</span>[] bindingElements = <span style="color: blue">new </span><span style="color: #2b91af">BindingElement</span>[2];
    bindingElements[0] = <span style="color: blue">new </span><span style="color: #2b91af">TextMessageEncodingBindingElement</span>();
    bindingElements[1] = <span style="color: blue">new </span><span style="color: #2b91af">HttpTransportBindingElement</span>();

    <span style="color: #2b91af">CustomBinding </span>binding = <span style="color: blue">new </span><span style="color: #2b91af">CustomBinding</span>(bindingElements);

    <span style="color: green">// 使用自定义绑定创建通道侦听器         
    </span><span style="color: #2b91af">IChannelListener</span>&lt;<span style="color: #2b91af">IReplyChannel</span>&gt; listener =
          binding.BuildChannelListener&lt;<span style="color: #2b91af">IReplyChannel</span>&gt;(
             <span style="color: blue">new </span><span style="color: #2b91af">Uri</span>(<span style="color: #a31515">"http://localhost:8887/StringService"</span>),
             <span style="color: blue">new </span><span style="color: #2b91af">BindingParameterCollection</span>());

    <span style="color: green">// 监听消息
    </span>listener.Open();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Listening for incoming channel connections"</span>);

    <span style="color: green">// 创建Reply通道
    </span><span style="color: #2b91af">IReplyChannel </span>channel = listener.AcceptChannel();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Channel accepted. Listening for messages"</span>);
    channel.Open();

    <span style="color: #2b91af">RequestContext </span>request = channel.ReceiveRequest();

    <span style="color: green">// 读取请求的消息
    </span><span style="color: #2b91af">Message </span>message = request.RequestMessage;
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Received"</span>);
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Action: {0}"</span>, message.Headers.Action);
    <span style="color: blue">string </span>body = message.GetBody&lt;<span style="color: blue">string</span>&gt;();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Message Content: {0}"</span>, body);

    <span style="color: green">// 发送响应消息
    </span><span style="color: #2b91af">Message </span>replymessage = <span style="color: #2b91af">Message</span>.CreateMessage(
        binding.MessageVersion,
        <span style="color: #a31515">"http://www.cnblogs.com/TerryLee/Encode"</span>,
         <span style="color: #a31515">"Hello : " </span>+ body);

    request.Reply(replymessage);

    <span style="color: green">// 释放对象
    </span>message.Close();
    request.Close();
    channel.Close();
    listener.Close();

    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Press Enter to exit"</span>);
    <span style="color: #2b91af">Console</span>.ReadLine();
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>现在运行服务端如图1所示，由于没有消息到达，所以ReceiveRequest()方法会阻塞： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="236" alt="TerryLee_WCF_31" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF9Part2_243/TerryLee_WCF_31_3.png" width="561" border="0"> 
<p>图 1 
<h2>客户端通道</h2>
<p>前面完成了服务端的工作，接下来我们看看如何在客户端直接使用通道模型进行通信。与服务端一致，请求消息的第一步是创建绑定，因为双方需要通过绑定就通信的细节达成一致。创建自定义绑定与服务端一致，如下代码所示：<pre class="code"><span style="color: green">// 创建绑定
</span><span style="color: #2b91af">BindingElement</span>[] bindingElements = <span style="color: blue">new </span><span style="color: #2b91af">BindingElement</span>[2];
bindingElements[0] = <span style="color: blue">new </span><span style="color: #2b91af">TextMessageEncodingBindingElement</span>();
bindingElements[1] = <span style="color: blue">new </span><span style="color: #2b91af">HttpTransportBindingElement</span>();

<span style="color: #2b91af">CustomBinding </span>binding = <span style="color: blue">new </span><span style="color: #2b91af">CustomBinding</span>(bindingElements);</pre><a href="http://11011.net/software/vspaste"></a>
<p>接下来需要使用刚才创建的绑定来构造通道工厂，在上一篇中我们提到，消息的接收方使用通道侦听器，而消息的请求方使用通道工厂，这次使用BuildChannelFactory()方法构造通道工厂并打开，如下代码所示：<pre class="code"><span style="color: green">// 使用绑定创建通道工厂
</span><span style="color: #2b91af">IChannelFactory</span>&lt;<span style="color: #2b91af">IRequestChannel</span>&gt; factory =
binding.BuildChannelFactory&lt;<span style="color: #2b91af">IRequestChannel</span>&gt;(
                 <span style="color: blue">new </span><span style="color: #2b91af">BindingParameterCollection</span>());
<span style="color: green">// 打开通道工厂
</span>factory.Open();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Channel factory opened"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>现在使用通道工厂的CreateChannel()方法来创建IRequestChannel，得到通道后，调用它的Open()方法以使其处于通信就绪状态，如下代码所示：<pre class="code"><span style="color: green">// 创建Request通道
</span><span style="color: #2b91af">IRequestChannel </span>channel = factory.CreateChannel(
   <span style="color: blue">new </span><span style="color: #2b91af">EndpointAddress</span>(<span style="color: #a31515">"http://localhost:8887/StringService"</span>));
channel.Open();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Request channel opened"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<p>打开通道之后，就可以创建消息并使用通道的 Request()方法发送请求并等待响应，这里我们发送的消息内容是“TerryLee”，当此方法返回时，我们将能够得到回复消息，可以读取该消息以发现终结点回复的内容，如下代码所示：<pre class="code"><span style="color: green">// 创建请求消息
</span><span style="color: #2b91af">Message </span>requestmessage = <span style="color: #2b91af">Message</span>.CreateMessage(
    binding.MessageVersion,
    <span style="color: #a31515">"http://www.cnblogs.com/TerryLee/Encode"</span>,
     <span style="color: #a31515">"TerryLee"</span>);

<span style="color: green">// 发送请求消息并接收响应消息
</span><span style="color: #2b91af">Message </span>replymessage = channel.Request(requestmessage);
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply message received"</span>);
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply action: {0}"</span>,
                      replymessage.Headers.Action);
<span style="color: blue">string </span>data = replymessage.GetBody&lt;<span style="color: blue">string</span>&gt;();
<span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply content: {0}"</span>, data);</pre><a href="http://11011.net/software/vspaste"></a>
<p>最后仍然是资源释放工作，关闭通道工厂、通道以及请求消息，如下代码所示：<pre class="code">replymessage.Close();
channel.Close();
factory.Close();</pre><a href="http://11011.net/software/vspaste"></a>
<p>完整的客户端代码为：<pre class="code"><span style="color: gray">/// &lt;summary&gt;
/// </span><span style="color: green">Author:TerryLee
</span><span style="color: gray">/// </span><span style="color: green">Url:http://www.cnblogs.com/terrylee
</span><span style="color: gray">/// &lt;/summary&gt;
</span><span style="color: blue">public static void </span>Main()
{
    <span style="color: green">// 创建绑定
    </span><span style="color: #2b91af">BindingElement</span>[] bindingElements = <span style="color: blue">new </span><span style="color: #2b91af">BindingElement</span>[2];
    bindingElements[0] = <span style="color: blue">new </span><span style="color: #2b91af">TextMessageEncodingBindingElement</span>();
    bindingElements[1] = <span style="color: blue">new </span><span style="color: #2b91af">HttpTransportBindingElement</span>();

    <span style="color: #2b91af">CustomBinding </span>binding = <span style="color: blue">new </span><span style="color: #2b91af">CustomBinding</span>(bindingElements);

    <span style="color: green">// 使用绑定创建通道工厂
    </span><span style="color: #2b91af">IChannelFactory</span>&lt;<span style="color: #2b91af">IRequestChannel</span>&gt; factory =
    binding.BuildChannelFactory&lt;<span style="color: #2b91af">IRequestChannel</span>&gt;(
                     <span style="color: blue">new </span><span style="color: #2b91af">BindingParameterCollection</span>());
    <span style="color: green">// 打开通道工厂
    </span>factory.Open();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Channel factory opened"</span>);

    <span style="color: green">// 创建Request通道
    </span><span style="color: #2b91af">IRequestChannel </span>channel = factory.CreateChannel(
       <span style="color: blue">new </span><span style="color: #2b91af">EndpointAddress</span>(<span style="color: #a31515">"http://localhost:8887/StringService"</span>));
    channel.Open();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Request channel opened"</span>);

    <span style="color: green">// 创建请求消息
    </span><span style="color: #2b91af">Message </span>requestmessage = <span style="color: #2b91af">Message</span>.CreateMessage(
        binding.MessageVersion,
        <span style="color: #a31515">"http://www.cnblogs.com/TerryLee/Encode"</span>,
         <span style="color: #a31515">"TerryLee"</span>);

    <span style="color: green">// 发送请求消息并接收响应消息
    </span><span style="color: #2b91af">Message </span>replymessage = channel.Request(requestmessage);
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply message received"</span>);
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply action: {0}"</span>,
                          replymessage.Headers.Action);
    <span style="color: blue">string </span>data = replymessage.GetBody&lt;<span style="color: blue">string</span>&gt;();
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Reply content: {0}"</span>, data);

    replymessage.Close();
    channel.Close();
    factory.Close();

    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Press Enter to exit"</span>);
    <span style="color: #2b91af">Console</span>.ReadLine();
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>最后运行时服务端如图2所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="266" alt="TerryLee_WCF_33" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF9Part2_243/TerryLee_WCF_33_3.png" width="580" border="0">&nbsp; <p>图 2 
<p>客户端如图3所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="280" alt="TerryLee_WCF_32" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF9Part2_243/TerryLee_WCF_32_3.png" width="580" border="0"> 
<p>图 3 
<h2>温故知新</h2>
<p>现在我们再回顾一下<a href="http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html">上一篇</a>中所讲的知识，通道对象模型是实现通道、通道侦听器和通道工厂所必需的一组核心接口。还提供一些基类以辅助自定义实现。可以看到通道模型中最重要的有三组接口：通道、通道侦听器和通道工厂。每个通道均实现一个或多个接口，称为通道形状接口或通道形状；通道侦听器负责侦听传入消息，即在消息的接收端，然后通过由通道侦听器创建的通道将这些消息传送到上面的层；通道工厂负责创建通道用于发送消息，即在消息的发送方，并在通道工厂关闭时，关闭通道工厂创建的所有通道。如图4所示： 
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="381" alt="TerryLee_WCF_24" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF9Part2_243/TerryLee_WCF_24_3.png" width="494" border="0"> 
<p>图 4 
<p>对照本文的示例代码，相信大家对于图4能够有更深的认识。 
<h2>总结</h2>
<p>本文我们通过一个简单的示例介绍了在通道模型中服务端是如何接收消息以及客户端是如何发送消息的，希望对大家有所帮助。</p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1333195.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43806/" target="_blank">[新闻]Python 3.0正式发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（8）：深度通道编程模型Part 1—设计篇</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 11 Nov 2008 14:36:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1331035.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html#Feedback</comments><slash:comments>35</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1331035.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1331035.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>从本质上说，WCF是一个通信服务框架，它允许我们使用不同的传输协议，使用不同的消息编码形式，跟不同的WS-*系列规范交互，而所有这些细节都是由通道堆栈来处理的。为了简化这些处理，在WCF中提供了两种模型，一是针对开发者的应用程序编程模型；二是用来通信的通道模型，这样对于开发者来说，只要了解应用程序编程模型就足够了，而不会涉及到通道模型，然而，对于通道模型进行必要的学习，可以让我们真正理解WCF中“通信”概念，了解WCF的 整个架构体系，从而构建出更加健壮的WCF服务或者对WCF框架进行扩展。在本文中，我们将进行深度了解WCF中的通道模型是如何设计的。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/11/WCF-Channel-Programming-Model-Design.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1331035.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43805/" target="_blank">[新闻]JavaFX千呼万唤始出来</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>回归Dos操作的快感，进入PowerShell世界</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sat, 08 Nov 2008 17:23:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1329918.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html#Feedback</comments><slash:comments>69</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1329918.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1329918.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_powershell.png" alt=""/></div>写下本篇文章源于参加Tech.Ed的一场关于Window PowerShell的课程。虽然之前也经常关注，但从没有亲自体验过。Windows PowerShell 是一种新的命令行外壳和脚本语言，用于进行系统管理和自动化任务，它建立在 .NET Framework 的基础上，可使 IT 专业人员和开发人员控制和自动完成Windows 和应用程序的管理。更为强大之处在于它可以调用.NET Framework中的类库，可以与COM、ADO、XML等交互。在本文中让我们一起来体会一下回归Doc操作的快感，进入强大无比的Windows PowerShell世界。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/09/Windows-PowerShell-Overview.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1329918.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43804/" target="_blank">[新闻]Moonlight: Linux 平台下的 Silverlight</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（7）：消息如何传递之绑定Part 2</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/06/WCF-Binding-Elements.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 06 Nov 2008 15:56:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/06/WCF-Binding-Elements.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1328513.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/06/WCF-Binding-Elements.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1328513.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1328513.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>在WCF专题系列（6）：消息如何传递之绑定Part 1一文中，我提到绑定由绑定元素组成，每个绑定元素用来描述终结点与客户端通信方式中的某个方面，在发送或接收消息时，每个绑定元素都表示一个处理步骤；运行时，绑定元素会创建必要的通道和侦听器，用以生成传出和传入通道堆栈。本文为消息如何传递之绑定第二部分，将详细介绍WCF内置的各种绑定元素，绑定元素之间的顺序以及如何创建一个自定义的绑定元素。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/06/WCF-Binding-Elements.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1328513.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43803/" target="_blank">[新闻]印度软件外包企业秘密收购中国公司</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（6）：消息如何传递之绑定Part 1</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/05/WCF-Binding-Overview.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Wed, 05 Nov 2008 14:44:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/05/WCF-Binding-Overview.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1327676.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/05/WCF-Binding-Overview.html#Feedback</comments><slash:comments>22</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1327676.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1327676.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>每个服务终结点都包含一个地址Address、一个绑定Binding 和一个契约Contract。契约指定可用的操作，绑定指定如何与服务进行通信，而地址指定查找服务的位置，在WCF专题系列前5篇中，深入了解了WCF中寻址的细节；从本文开始，将深入了解经典“ABC”中的B，即绑定Binding，了解它的原理，如何使用绑定通信以及在元数据中如何公开。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/05/WCF-Binding-Overview.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1327676.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43802/" target="_blank">[新闻]华人高管陆奇出任微软互联网业务总裁</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>.NET Framework 4.0海报</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/31/dotnet-framework-v4-poster.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 30 Oct 2008 16:44:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/31/dotnet-framework-v4-poster.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1323378.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/31/dotnet-framework-v4-poster.html#Feedback</comments><slash:comments>26</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1323378.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1323378.html</trackback:ping><description><![CDATA[<p>在PDC 2008大会上，微软发布了一款非常漂亮的.NET Framework 4.0海报，在海报中展示了.NET Framework 3.5 SP1和.NET Framework 4中新添加的功能。同时还使用Silverlight 2技术开发了一个Deep Zoom的版本，可以在线预览，另外也可以下载PDF版本收藏。 <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="365" alt="TerryLee_0202" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/.NETFramework4.0_692/TerryLee_0202_3.png" width="541" border="0">  <p><a href="http://tinyurl.com/DotNetFramework4PosterDeepZoom">Deep Zoom在线版</a> <p><a href="http://tinyurl.com/PDC2008-NETFX4PDF">下载PDF版本</a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1323378.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43801/" target="_blank">[新闻]AT&T将裁员12,000人</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（5）：深入WCF寻址Part 5—逻辑地址和物理地址</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Thu, 30 Oct 2008 16:16:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1323370.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1323370.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1323370.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>在WCF中，每个服务终结点都与两个地址相关联，一个逻辑地址和一个物理地址，逻辑地址就是SOAP消息的目标地址，即前面不止一次提到的“To”地址，而物理地址是WCF侦听器真正监听的地址。在WCF中，逻辑地址称之为终结点地址Endpoint Address，而物理地址则称之为监听地址ListenUri。

本文将详细介绍WCF中的物理地址和逻辑地址，以及如何使用tcpTrace来进行SOAP消息的跟踪。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1323370.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43801/" target="_blank">[新闻]AT&T将裁员12,000人</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（4）：深入WCF寻址Part 4—自定义消息筛选器</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Wed, 29 Oct 2008 16:44:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1322616.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1322616.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1322616.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>在WCF专题系列（3）：深入WCF寻址Part 3—消息过滤引擎一文中，详细介绍了WCF中的消息筛选引擎，包括消息筛选器和筛选器表，每个EndpointDispatcher都包含了两个消息筛选器，默认的地址过滤器是EndpointAddressMessageFilter，默认的契约过滤器是ActionMessageFilter，这些是可以通过Behavior来改变的。本文我们将学习如何创建一个自定义的消息过滤器，并通过自定义Behavior来改变EndpointDispatcher的默认过滤器。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1322616.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43800/" target="_blank">[新闻]微软本月安全公告预告：6个危急、2个重要</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Silverlight Toolkit预览Part 1：介绍</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/29/Silverlight-Toolkit-overview-part1.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 28 Oct 2008 18:06:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/29/Silverlight-Toolkit-overview-part1.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1321780.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/29/Silverlight-Toolkit-overview-part1.html#Feedback</comments><slash:comments>40</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1321780.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1321780.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_silverlight2.gif" alt=""/></div>Silverlight Toolkit是由微软提供的一系列的Silverlight控件、组件和工具的集合，不仅免费且完全开源，当前发布的版本中包括12个控件和6套非常酷的主题样式，覆盖的范围包括图表、样式、布局以及用户输入，效果预览：&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/29/Silverlight-Toolkit-overview-part1.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1321780.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43799/" target="_blank">[新闻]微软发布云计算版第四代模块化数据中心</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>微软发布Enterprise Library 4.1和Unity 1.2</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/29/enterprise-library-v-4-1-and-unity-application-block-v-1-2-Released.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 28 Oct 2008 16:58:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/29/enterprise-library-v-4-1-and-unity-application-block-v-1-2-Released.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1321774.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/29/enterprise-library-v-4-1-and-unity-application-block-v-1-2-Released.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1321774.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1321774.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_pandp.png" alt=""/></div>微软模式与实践团队今天发布了Enterprise Library 4.1和Unity 1.2版本，这次发布的主要新特性如下：

1. 支持Visual Studio 2008 SP1

2. Unity应用程序块中加入了拦截机制

3. 性能提升

4. 配置工具的可用性提升

5. Bugs修复。

在Unity 1.2中有如下几点改进：

1. 简化了对象的创建，尤其是层次对象的结构和依赖

2. 通过为容器推迟组件的配置增加了灵活性

3. 服务定位能力增强，允许客户存储或者缓存容器

4. 实例和类型拦截&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/29/enterprise-library-v-4-1-and-unity-application-block-v-1-2-Released.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1321774.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43799/" target="_blank">[新闻]微软发布云计算版第四代模块化数据中心</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>强烈推荐：应用程序架构指导包v2.0</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/28/patterns-and-practices-Application-Architecture-Guide-v2-Beta1-Release.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Tue, 28 Oct 2008 04:00:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/28/patterns-and-practices-Application-Architecture-Guide-v2-Beta1-Release.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1321149.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/28/patterns-and-practices-Application-Architecture-Guide-v2-Beta1-Release.html#Feedback</comments><slash:comments>25</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1321149.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1321149.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_pandp.png" alt=""/></div>应用程序架构指导包由微软模式与实践团队负责编写，为基于.NET平台的应用程序设计提供了一些指导，现在v2.0 Beta版本已经发布，包括的内容有应用程序架构基础、设计、分层、设计模式等等，设计的应用程序类型有Mobile Application，Office Business Application (OBA)，Rich Client Application ，Rich Internet Application (RIA)，Web Application等 ，之前园子里的蜡笔小巢也有过介绍。完整的目录如下所示&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/28/patterns-and-practices-Application-Architecture-Guide-v2-Beta1-Release.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1321149.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43798/" target="_blank">[新闻]IBM发布“无微软”虚拟桌面系统</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（3）：深入WCF寻址Part 3—消息过滤引擎</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/27/WCF-Addressing-Part3-Message-Filter.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Mon, 27 Oct 2008 15:58:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/27/WCF-Addressing-Part3-Message-Filter.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1320874.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/27/WCF-Addressing-Part3-Message-Filter.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1320874.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1320874.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_wcf.png" alt=""/></div>通过前面两篇的介绍，对Web服务寻址规范以及在WCF开发中终结点地址有了深入的认识。本文我们继续深入WCF寻址第三部分内容，当消息传入时，如何来确定匹配的终结点，就是我们本文要讲到的消息筛选引擎，在WCF中，消息筛选器引擎包括两个重要的组成部分：筛选器和筛选器表。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/10/27/WCF-Addressing-Part3-Message-Filter.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1320874.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43797/" target="_blank">[新闻]2008年12月5日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（2）：深入WCF寻址Part 2—自定义寻址报头</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/26/WCF-Addressing-part2.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 26 Oct 2008 07:52:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/26/WCF-Addressing-part2.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1319852.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/26/WCF-Addressing-part2.html#Feedback</comments><slash:comments>24</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1319852.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1319852.html</trackback:ping><description><![CDATA[<h2>概述</h2> <p>在<a href="http://www.cnblogs.com/Terrylee/archive/2008/10/25/wcf-addressing-part1.html">WCF专题系列（1）：深入WCF寻址Part1</a>一文中，我们对Web服务寻址规范做了一些认识，了解了终结点引用和消息信息报头两种结构，该规范在Web服务中的地位举足轻重，后续我们会经常提到该规范。在本文中，我们将继续深入WCF寻址的内容，包括元数据中的终结点地址，自定义寻址标头等相关信息。  <h2>终结点地址定义</h2> <p>了解了Web服务寻址规范，再回到WCF，在WCF中，终结点地址是由EndpointAddress类来表示的，它其中很重要的几个部分是：一个表示服务地址的统一资源定位符 (URI)，一个表示服务的安全标识的 Identity 和一个可选的 Headers 集合，其中Headers用于标识终结点或与终结点交互的更多详细寻址信息。如图1所示： <p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="190" alt="TerryLee_WCF_02" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF2WCFPart2_DD41/TerryLee_WCF_02_3.png" width="496" border="0">&nbsp;&nbsp; <p>图1  <p>记的我在<a href="http://www.cnblogs.com/Terrylee/archive/2008/10/25/wcf-addressing-part1.html">WCF专题系列（1）：深入WCF寻址Part1</a>一文提到过，每个终结点引用都可以包含一些添加额外标识信息的引用参数，即寻址标头，在 WCF 中，将这些引用参数建模为 AddressHeader 类的实例，这里的Headers属性就是这些实例的集合，可以通过AddressHeader类提供的静态方法CreateAddressHeader来创建一个AddressHeader实例，如下代码所示： <pre class="code"><span style="color: #2b91af">AddressHeader </span>header = <span style="color: #2b91af">AddressHeader</span>.CreateAddressHeader(<span style="color: #a31515">"basic"</span>,
                        <span style="color: #a31515">"http://www.cnblogs.com/terrylee"</span>, <span style="color: #a31515">"Terrylee"</span>);</pre><a href="http://11011.net/software/vspaste"></a>
<h2>指定终结点地址</h2>
<p>在WCF中提供了基址技术，这使的我们在指定终结点地址时可以酌情选用相对地址或者绝对地址，指定绝对地址的方法是在终结点定义中提供完全限定的地址，如下代码所示： <pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">service </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Service.CalculatorService</span>"
         <span style="color: red">behaviorConfiguration</span><span style="color: blue">=</span>"<span style="color: blue">calculatorBehavior</span>"<span style="color: blue">&gt;

  &lt;</span><span style="color: #a31515">endpoint </span><span style="color: red">address</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8887/CalculatorService</span>"
            <span style="color: red">binding </span><span style="color: blue">=</span>"<span style="color: blue">basicHttpBinding</span>"
            <span style="color: red">contract</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Contract.ICalculator</span>"<span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">endpoint</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">service</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>使用绝对地址固然简单，但是如果我们的服务需要公开多个终结点，而这些终结点地址又具有相同的基地址时，也许相对地址是更好的选择。在创建服务宿主对象时，提供一个基地址，如下代码所示： <pre class="code"><span style="color: blue">using </span>(<span style="color: #2b91af">ServiceHost </span>calculatorServiceHost =
        <span style="color: blue">new </span><span style="color: #2b91af">ServiceHost</span>(<span style="color: blue">typeof</span>(<span style="color: #2b91af">CalculatorService</span>),
        <span style="color: blue">new </span><span style="color: #2b91af">Uri</span>(<span style="color: #a31515">"http://localhost:8887/CalculatorService"</span>)))
{
    calculatorServiceHost.Opened += <span style="color: blue">delegate
    </span>{
        <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Service begin to listen via the Address:{0}"</span>,
            calculatorServiceHost.BaseAddresses[0].ToString());
    };

    calculatorServiceHost.Open();
    <span style="color: #2b91af">Console</span>.Read();
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>又或者同时在配置文件中指定基地址，这样就无须在每个终结点中指定绝对地址了，如下代码所示： <pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">service </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Service.CalculatorService</span>"
         <span style="color: red">behaviorConfiguration</span><span style="color: blue">=</span>"<span style="color: blue">calculatorBehavior</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">host</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">baseAddresses</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">add </span><span style="color: red">baseAddress</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8887/Calculator</span>"<span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">baseAddresses</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">host</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">endpoint </span><span style="color: red">address</span><span style="color: blue">=</span>"<span style="color: blue">myservice1</span>"
            <span style="color: red">binding </span><span style="color: blue">=</span>"<span style="color: blue">basicHttpBinding</span>"
            <span style="color: red">contract</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Contract.ICalculator</span>"<span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">endpoint</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">endpoint </span><span style="color: red">address</span><span style="color: blue">=</span>"<span style="color: blue">myservice2</span>"
            <span style="color: red">binding </span><span style="color: blue">=</span>"<span style="color: blue">wsHttpBinding</span>"
            <span style="color: red">contract</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Contract.ICalculator</span>"<span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">endpoint</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">service</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>但请注意，基址技术是为我们在配置终结点时提供了方便，客户端对它是毫无所知的，客户端看到的仍然是绝对地址，在打开服务宿主时，它会匹配所有的相对地址，从而为每个终结点提供相应的绝对地址，如上面的示例，可以在WSDL中看到： <pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">wsdl:service </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">CalculatorService</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">wsdl:port </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">BasicHttpBinding_ICalculator</span>" <span style="color: red">binding</span><span style="color: blue">=</span>"<span style="color: blue">tns:BasicHttpBinding_ICalculator</span>"<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">soap:address </span><span style="color: red">location</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8887/Calculator/myservice1</span>" <span style="color: blue">/&gt;
  &lt;/</span><span style="color: #a31515">wsdl:port</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">wsdl:port </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">WSHttpBinding_ICalculator</span>" <span style="color: red">binding</span><span style="color: blue">=</span>"<span style="color: blue">tns:WSHttpBinding_ICalculator</span>"<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">soap12:address </span><span style="color: red">location</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8887/Calculator/myservice2</span>" <span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">wsa10:EndpointReference</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">wsa10:Address</span><span style="color: blue">&gt;</span>http://localhost:8887/Calculator/myservice2<span style="color: blue">&lt;/</span><span style="color: #a31515">wsa10:Address</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">Identity </span><span style="color: red">xmlns</span><span style="color: blue">=</span>"<span style="color: blue">http://schemas.xmlsoap.org/ws/2006/02/addressingidentity</span>"<span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Upn</span><span style="color: blue">&gt;</span>TerryLee-PC\TerryLee<span style="color: blue">&lt;/</span><span style="color: #a31515">Upn</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">Identity</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">wsa10:EndpointReference</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">wsdl:port</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">wsdl:service</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>如果在指定了基地址的情况下，有以下几种情况：指定相对地址为空，终结点地址与基地址相同；指定相对地址不为空，追加相对地址到基地址上；指定一个绝对地址，基地址不起作用，终结点地址仍然为指定的绝对地址；指定一个绝对地址和一个与基地址不同的绑定，基地址不起作用。现在有这样一段配置信息： <pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">service </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Service.CalculatorService</span>"
         <span style="color: red">behaviorConfiguration</span><span style="color: blue">=</span>"<span style="color: blue">calculatorBehavior</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">host</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">baseAddresses</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">add </span><span style="color: red">baseAddress</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8887/Calculator</span>"<span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">baseAddresses</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">host</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">endpoint </span><span style="color: red">address</span><span style="color: blue">=</span>""
            <span style="color: red">binding </span><span style="color: blue">=</span>"<span style="color: blue">wsHttpBinding</span>"
            <span style="color: red">contract</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Contract.ICalculator</span>"<span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">endpoint</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">endpoint </span><span style="color: red">address</span><span style="color: blue">=</span>"<span style="color: blue">myservice2</span>"
            <span style="color: red">binding </span><span style="color: blue">=</span>"<span style="color: blue">wsHttpBinding</span>"
            <span style="color: red">contract</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Contract.ICalculator</span>"<span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">endpoint</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">endpoint </span><span style="color: red">address</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8886/CalculatorService</span>"
            <span style="color: red">binding </span><span style="color: blue">=</span>"<span style="color: blue">wsHttpBinding</span>"
            <span style="color: red">contract</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Contract.ICalculator</span>"<span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">endpoint</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">endpoint </span><span style="color: red">address</span><span style="color: blue">=</span>"<span style="color: blue">net.tcp://localhost:8885/Calculator</span>"
            <span style="color: red">binding </span><span style="color: blue">=</span>"<span style="color: blue">netTcpBinding</span>"
            <span style="color: red">contract</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Contract.ICalculator</span>"<span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">endpoint</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">service</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>可以在ServiceHost启动后，输出所有的终结点地址和绑定信息，如下代码： <pre class="code"><span style="color: #2b91af">ServiceDescription </span>desc = calculatorServiceHost.Description;
<span style="color: blue">foreach </span>(<span style="color: #2b91af">ServiceEndpoint </span>endpoint <span style="color: blue">in </span>desc.Endpoints)
{
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Endpoint - address:  {0}"</span>, endpoint.Address);
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"           binding:  {0}"</span>, endpoint.Binding.Name);
    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"           contract: {0}"</span>, endpoint.Contract.Name);
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>输出结果如图2所示：
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="314" alt="TerryLee_WCF_05" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF2WCFPart2_DD41/TerryLee_WCF_05_3.png" width="580" border="0">&nbsp;&nbsp; <p>图2 
<h2>元数据中终结点地址</h2>
<p>终结点地址在WSDL中表示为对应终结点的 wsdl:port元素内的终结点引用（EndpointReference）元素。终结点引用包含终结点的地址以及所有的地址属性，如下示例代码所示： <pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">wsdl:service </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">CalculatorService</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">wsdl:port </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">WSHttpBinding_ICalculator</span>" <span style="color: red">binding</span><span style="color: blue">=</span>"<span style="color: blue">tns:WSHttpBinding_ICalculator</span>"<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">soap12:address </span><span style="color: red">location</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8887/Calculator</span>" <span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">wsa10:EndpointReference</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">wsa10:Address</span><span style="color: blue">&gt;</span>http://localhost:8887/Calculator<span style="color: blue">&lt;/</span><span style="color: #a31515">wsa10:Address</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">Identity </span><span style="color: red">xmlns</span><span style="color: blue">=</span>"<span style="color: blue">http://schemas.xmlsoap.org/ws/2006/02/addressingidentity</span>"<span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Upn</span><span style="color: blue">&gt;</span>TerryLee-PC\TerryLee<span style="color: blue">&lt;/</span><span style="color: #a31515">Upn</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">Identity</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">wsa10:EndpointReference</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">wsdl:port</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">wsdl:service</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<h2>自定义寻址报头</h2>
<p>在本文的终结点定义一节，我们提到了寻址报头，在某些情况下，我们可能希望通过自定义寻址报头来解决一些复杂的问题，如根据根据传入的寻址报头中是否包含某些信息，将其转发到不同的终结点，通过自定义寻址报头，可以实现SOAP消息的无限扩展，放置任何希望的控制信息到SOAP消息。如下面的代码： <pre class="code"><span style="color: blue">using </span>(<span style="color: #2b91af">ServiceHost </span>calculatorServiceHost =
    <span style="color: blue">new </span><span style="color: #2b91af">ServiceHost</span>(<span style="color: blue">typeof</span>(<span style="color: #2b91af">CalculatorService</span>),
    <span style="color: blue">new </span><span style="color: #2b91af">Uri</span>(<span style="color: #a31515">"http://localhost:8887/CalculatorService"</span>)))
{
    calculatorServiceHost.Opened += <span style="color: blue">delegate
    </span>{
        <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">"Service begin to listen via the Address:{0}"</span>,
            calculatorServiceHost.BaseAddresses[0].ToString());
    };

    <span style="color: #2b91af">AddressHeader </span>header =
        <span style="color: #2b91af">AddressHeader</span>.CreateAddressHeader(<span style="color: #a31515">"basic"</span>,
        <span style="color: #a31515">"http://www.cnblogs.com/terrylee"</span>, <span style="color: #a31515">"Terrylee"</span>);

    <span style="color: #2b91af">EndpointAddress </span>ea = <span style="color: blue">new </span><span style="color: #2b91af">EndpointAddress</span>(
        <span style="color: blue">new </span><span style="color: #2b91af">Uri</span>(<span style="color: #a31515">"http://localhost:8887/CalculatorService"</span>), header);

    calculatorServiceHost.Description.Endpoints.Add(
        <span style="color: blue">new </span><span style="color: #2b91af">ServiceEndpoint</span>(
            <span style="color: #2b91af">ContractDescription</span>.GetContract(<span style="color: blue">typeof</span>(<span style="color: #2b91af">ICalculator</span>)),
            <span style="color: blue">new </span><span style="color: #2b91af">WSHttpBinding</span>(),
            ea));

    <span style="color: #2b91af">ServiceMetadataBehavior </span>behavior = <span style="color: blue">new </span><span style="color: #2b91af">ServiceMetadataBehavior</span>();
    behavior.HttpGetEnabled = <span style="color: blue">true</span>;
    calculatorServiceHost.Description.Behaviors.Add(behavior);

    calculatorServiceHost.Open();
    <span style="color: #2b91af">Console</span>.Read();
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>我们在WSDL中可以看到该自定义的报头，它作为终结点引用的引用参数： <pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">wsdl:service </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">CalculatorService</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">wsdl:port </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">WSHttpBinding_ICalculator</span>" <span style="color: red">binding</span><span style="color: blue">=</span>"<span style="color: blue">tns:WSHttpBinding_ICalculator</span>"<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">soap12:address </span><span style="color: red">location</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8887/CalculatorService</span>" <span style="color: blue">/&gt;
    &lt;</span><span style="color: #a31515">wsa10:EndpointReference</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">wsa10:Address</span><span style="color: blue">&gt;</span>http://localhost:8887/CalculatorService<span style="color: blue">&lt;/</span><span style="color: #a31515">wsa10:Address</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">wsa10:ReferenceParameters</span><span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">basic </span><span style="color: red">xmlns</span><span style="color: blue">=</span>"<span style="color: blue">http://www.cnblogs.com/terrylee</span>"<span style="color: blue">&gt;</span>Terrylee<span style="color: blue">&lt;/</span><span style="color: #a31515">basic</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">wsa10:ReferenceParameters</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">Identity </span><span style="color: red">xmlns</span><span style="color: blue">=</span>"<span style="color: blue">http://schemas.xmlsoap.org/ws/2006/02/addressingidentity</span>"<span style="color: blue">&gt;
        &lt;</span><span style="color: #a31515">Upn</span><span style="color: blue">&gt;</span>TerryLee-PC\TerryLee<span style="color: blue">&lt;/</span><span style="color: #a31515">Upn</span><span style="color: blue">&gt;
      &lt;/</span><span style="color: #a31515">Identity</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">wsa10:EndpointReference</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">wsdl:port</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">wsdl:service</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>截获到SOAP消息可以看到，在消息报头中添加了basic这样的信息，如下代码所示： <pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">s:Envelope </span><span style="color: red">xmlns:s</span><span style="color: blue">=</span>"<span style="color: blue">http://schemas.xmlsoap.org/soap/envelope/</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">s:Header</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">basic </span><span style="color: red">xmlns</span><span style="color: blue">=</span>"<span style="color: blue">http://www.cnblogs.com/terrylee</span>"<span style="color: blue">&gt;</span>Terrylee<span style="color: blue">&lt;/</span><span style="color: #a31515">basic</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">To </span><span style="color: red">s:mustUnderstand</span><span style="color: blue">=</span>"<span style="color: blue">1</span>"<span style="color: blue">&gt;</span>http://localhost:8887/CalculatorService<span style="color: blue">&lt;/</span><span style="color: #a31515">To</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Action </span><span style="color: red">s:mustUnderstand</span><span style="color: blue">=</span>"<span style="color: blue">1</span>"<span style="color: blue">&gt;</span>http://tempuri.org/ICalculator/Add<span style="color: blue">&lt;/</span><span style="color: #a31515">Action</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">s:Header</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">s:Body</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">Add </span><span style="color: red">xmlns</span><span style="color: blue">=</span>"<span style="color: blue">http://tempuri.org/</span>"<span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">x</span><span style="color: blue">&gt;</span>1<span style="color: blue">&lt;/</span><span style="color: #a31515">x</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">y</span><span style="color: blue">&gt;</span>2<span style="color: blue">&lt;/</span><span style="color: #a31515">y</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">Add</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">s:Body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">s:Envelope</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<p>当然我们也可以通过配置的方式来自定义寻址报头，如下代码所示： <pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">service </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Service.CalculatorService</span>"
         <span style="color: red">behaviorConfiguration</span><span style="color: blue">=</span>"<span style="color: blue">calculatorBehavior</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">host</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">baseAddresses</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">add </span><span style="color: red">baseAddress</span><span style="color: blue">=</span>"<span style="color: blue">http://localhost:8887/Calculator</span>"<span style="color: blue">/&gt;
    &lt;/</span><span style="color: #a31515">baseAddresses</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">host</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">endpoint </span><span style="color: red">address</span><span style="color: blue">=</span>""
            <span style="color: red">binding </span><span style="color: blue">=</span>"<span style="color: blue">wsHttpBinding</span>"
            <span style="color: red">contract</span><span style="color: blue">=</span>"<span style="color: blue">TerryLee.WCFAddressing.Contract.ICalculator</span>"<span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">headers</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">basic </span><span style="color: red">xmlns</span><span style="color: blue">=</span>"<span style="color: blue">http://www.cnblogs.com/terrylee</span>"<span style="color: blue">&gt;</span>Terrylee<span style="color: blue">&lt;/</span><span style="color: #a31515">basic</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">headers</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">endpoint</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">service</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<h2>结束语</h2>
<p>本文相对于<a href="http://www.cnblogs.com/Terrylee/archive/2008/10/25/wcf-addressing-part1.html">WCF专题系列（1）：深入WCF寻址Part1</a>来说，注重于实际的使用，介绍了指定终结点地址、元数据中的终结点地址、自定义消寻址报头等，在下一篇中，我们将继续深入WCF寻址，探讨消息筛选器等问题。WCF寻址相关文章：</p>
<p><a href="http://www.cnblogs.com/Terrylee/archive/2008/10/31/WCF-Addressing-ListenUri-and-EndpointAddress.html">WCF专题系列（5）：深入WCF寻址Part 5—逻辑地址和物理地址</a> </p>
<p><a href="http://www.cnblogs.com/Terrylee/archive/2008/10/30/WCF-Addressing-Part3-Customize-Message-Filter.html">WCF专题系列（4）：深入WCF寻址Part 4—自定义消息筛选器</a> </p>
<p><a href="http://www.cnblogs.com/Terrylee/archive/2008/10/27/WCF-Addressing-Part3-Message-Filter.html">WCF专题系列（3）：深入WCF寻址Part 3—消息过滤引擎</a> </p>
<p><a href="http://www.cnblogs.com/Terrylee/archive/2008/10/25/WCF-addressing-part1.html">WCF专题系列（1）：深入WCF寻址Part 1—Web服务寻址规范</a></p><img src ="http://www.cnblogs.com/Terrylee/aggbug/1319852.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43796/" target="_blank">[新闻]Google和Facebook同日推Connect数据迁移功能</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WCF后传系列（1）：深入WCF寻址Part 1—Web服务寻址规范</title><link>http://www.cnblogs.com/Terrylee/archive/2008/10/25/WCF-addressing-part1.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Fri, 24 Oct 2008 16:08:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/10/25/WCF-addressing-part1.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1319127.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/10/25/WCF-addressing-part1.html#Feedback</comments><slash:comments>32</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1319127.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1319127.html</trackback:ping><description><![CDATA[<h2>概述</h2> <p>众所周知，WCF服务的所有通信都是通过服务的终结点发生的，每个 服务终结点都包含一个地址Address、一个绑定Binding 和一个契约Contract。契约指定可用的操作，绑定指定如何与服务进行通信，而地址指定查找服务的位置，即非常经典的“ABC”。WCF用多种不同的通信协议为公开服务终结点和与其通信提供了灵活的模式，在WCF专题系列的第一部分，我将围绕终结点的寻址细节展开讨论，再此之前，我们先看一下WCF的编程模型，如图1所示：  <p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="389" alt="TerryLee_WCF_01" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF1WCFPart1_EC2/TerryLee_WCF_01_5.png" width="447" border="0">  <p>图1  <h2>Web服务寻址规范</h2> <p>在 WCF 中，终结点地址是按照Web服务寻址 WS-Addressing 规范中的定义建立终结点引用（Endpoint Reference，EPR）的模型，我们有必要对Web服务寻址规范来做一个认识，这里先提出一个问题，为什么需要Web服务寻址？一方面SOAP如果要做到真正的与传输协议无关，就要以一种与传输协议无关的方式来定义消息的接收者与消息返回的地址；另一方面，定义寻址信息有助于在发生网络错误或丢失响应的情况下将消息返回给请求者；最后一套完善的寻址机制使的复杂的交互模式成为可能，如图2所示：  <p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="532" alt="TerryLee_WCF_04" src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/WindowsLiveWriter/WCF1WCFPart1_EC2/TerryLee_WCF_04_3.png" width="532" border="0">  <p>图2  <p>在WS-Addressing中，其实就两个概念：终结点引用（Endpoint Reference）和SOAP结构的消息信息报头（Message Information Headers）。如下面的示例表示将一条SOAP 1.2的消息发送到http://fabrikam123.com/Purchasing。：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">S:Envelope </span><span style="color: red">xmlns:S</span><span style="color: blue">=</span>"<span style="color: blue">http://www.w3.org/2002/12/soap-envelope</span>"
   <span style="color: red">xmlns:wsa</span><span style="color: blue">=</span>"<span style="color: blue">http://schemas.xmlsoap.org/ws/2003/03/addressing</span>"<span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">S:Header</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">wsa:ReplyTo</span><span style="color: blue">&gt;
      &lt;</span><span style="color: #a31515">wsa:Address</span><span style="color: blue">&gt;</span>http://business456.com/client1<span style="color: blue">&lt;/</span><span style="color: #a31515">wsa:Address</span><span style="color: blue">&gt;
    &lt;/</span><span style="color: #a31515">wsa:ReplyTo</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">wsa:To</span><span style="color: blue">&gt;</span>http://fabrikam123.com/Purchasing<span style="color: blue">&lt;/</span><span style="color: #a31515">wsa:To</span><span style="color: blue">&gt;
    &lt;</span><span style="color: #a31515">wsa:Action</span><span style="color: blue">&gt;</span>http://fabrikam123.com/SubmitPO<span style="color: blue">&lt;/</span><span style="color: #a31515">wsa:Action</span><span style="color: blue">&gt;
  &lt;/</span><span style="color: #a31515">S:Header</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">S:Body</span><span style="color: blue">&gt;
    </span>......
  <span style="color: blue">&lt;/</span><span style="color: #a31515">S:Body</span><span style="color: blue">&gt;
&lt;/</span><span style="color: #a31515">S:Envelope</span><span style="color: blue">&gt;</span></pre><a href="http://11011.net/software/vspaste"></a>
<h2>终结点引用</h2>
<p>Web 服务终结点是一个可以引用的实体、处理器或可以作为 Web 服务消息目标的资源，而终结点引用传达了标识或者引用一个 Web 服务终结点所需的信息，它的使用方式可以有多种：终结点引用适用于传达访问 Web 服务终结点所需的信息，也可以在 Web 服务间往返的各条消息提供地址。如下面的代码表示了终结点引用的信息集：<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">wsa:EndpointReference</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">wsa:Address</span><span style="color: blue">&gt;xs:anyURI&lt;/</span><span style="color: #a31515">wsa:Address</span><span style="color: blue">&gt;
  &lt;</span><span style="color: #a31515">wsa:ReferenceProperties</span><span style="color: blue">&gt;... &lt;/</span><span style="color: #a31515">wsa:ReferenceProperties</span><span style="color: blue">&gt; ?
  &lt;</span><span style="color: #a31515">wsa:ReferenceParameters</span><span style="color: blue">&gt;... &lt;/</span><span style="color: #a31515">wsa:ReferenceParameters</span><span style="color: blue">&gt; ?
  &lt;</span><span style="color: #a31515">wsa:PortType</span><span style="color: blue">&gt;xs:QName&lt;/</span><span style="color: #a31515">wsa:PortType</span><span style="color: blue">&gt; ?
  &lt;</span><span style="color: #a31515">wsa:ServiceName </span><span style="color: red">PortName</span><span style="color: blue">="xs:NCName"?&gt;xs:QName&lt;/</span><span style="color: #a31515">wsa:ServiceName</span><span style="color: blue">&gt; ?
  &lt;</span><span style="col