代码改变世界

WCF 第十三章 可编程站点 URI和UriTemplates

2011-06-02 07:14  DanielWise  阅读(2324)  评论(2编辑  收藏  举报
从.NET Framework v1.0开始微软就支持了URIs. System.Uri类允许开发人员在一个URI内定义并截取基本信息。这个类允许开发人员访问比如计划,路径和机器名等信息。向网络客户端比如System.Windows.Forms.WebBrowser控制或者System.Net.WebClient类传输一个URI是很好的。System.Uri类的依赖类是System.UriBuilder类。这个类提供了一种方式来修改System.Uri类而不用创建另外一个System.Uri实例。这些类是使用基于HTTP协议的URIs的基础。目前开发人员使用的话还需要额外的能力来支持REST架构类型。
  表13.1显示了开发人员在URIs中嵌入字符串作为查询字符串参数或者作为路径的一部分。System.Uri或者System.UriBuilder类不允许在这个解决方案下创建和截取URIs. 另外一种解决方案已经用来创建和截取基于确定命名令牌模式的URIs。它们也定义了参数如何从URIs截取。.NET Framework 3.5介绍了一个新的可以提供一个持续的方式来创建和截取URIs基于模式的称作System.UriTemplate的类。这个类定义一个基于命名令牌的模式。令牌在一个模式中使用大括号表示。例如,模式/finance/info?q={symbol}确定了一个被作为一个查询字符串参数发送的股票符号。命名令牌也可以嵌入到URI路径中作为其一部分且不仅限于查询字符串参数。例如,下面的模式,/browse/{word},确定了一个URI路径内的参数。System.Uri实例可以基于这些模式创建或者截取。我们现在将检查我们如何使用System.UriTemplate类来实现这个。
创建URIs
列表13.1显示了我们可以如何创建基于System.UriTemplates类的System.Uri实例的例子。第一个例子使用BindByPosition方法来创建一个System.Uri实例去收集Yahoo!股票价格。第二个例子使用BindByName方法来传递一对键/值来创建一个System.Uri实例去收集Google股票价格。
列表13.1 使用UriTemplate创建参数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;

namespace EssentialWCF
{
    class Program
    {
        static void Main(string[] args)
        {
            string symbol = "MSFT";

            //BindByPosition
            Uri YahooStockBaseUri = new Uri("http://finance.yahoo.com");
            UriTemplate yahooStockUriTemplate = new UriTemplate("/d/quotes?s={symbol}&f=sl1t1d1");
            Uri YhaooStockUri = yahooStockUriTemplate.BindByPosition(YahooStockBaseUri, symbol);
            Console.WriteLine(YhaooStockUri.ToString());

            //BindByName
            Uri GoogleStockBaseUri = new Uri("http://finance.google.com");
            UriTemplate GoogleStockUriTemplate = new UriTemplate("/finance/info?q={symbol}");
            NameValueCollection GoogleParams = new NameValueCollection();
            GoogleParams.Add("symbol", symbol);
            Uri GoogleStockUri = GoogleStockUriTemplate.BindByName(GoogleStockBaseUri, GoogleParams);

            Console.WriteLine(GoogleStockUri.ToString());
            Console.ReadLine();
        }
    }
}
截取URIs
我们刚刚看了创建基于模式的System.Uri实例是多么简单。列表13.2显示我们如何使用现有的URIs并截取出我们需要的参数。这次也是两个例子。第一个例子显示了我们可以如何截取基于查询字符串参数的参数。第二个例子显示我们如何截取基于一个路径的参数。在这两个例子中,我们可以解析出一系列基于一个模式的名/值对。我们将会在“为站点创建操作”部分看到如何使用UriTemplate来分发基于URIs的网络服务。
列表13.2 使用UriTemplate匹配参数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EssentialWCF.UriTemplate2
{
    class Program2
    {
        static void Main(string[] args)
        {
            Uri YahooStockBaseUri = new Uri("http://finance.yahoo.com");
            UriTemplate yahooStockUriTemplate = new UriTemplate("/d/quotes?s={symbol}");
            Uri yahooStockUri = new Uri("http://finance.yahoo.com/d/quotes?s=MSFT&f=spt1d");;
            UriTemplateMatch match = yahooStockUriTemplate.Match(YahooStockBaseUri, yahooStockUri);

            foreach (string key in match.BoundVariables.Keys)
            {
                Console.WriteLine(String.Format("{0}: {1}", key, match.BoundVariables[key]));
            }
            Console.WriteLine();

            Uri ReferenceDotComBaseUri = new Uri("http://dictionary.reference.com");
            UriTemplate ReferenceDotComTemplate = new UriTemplate("/browse/{word}");

            Uri referenceDotComUri = new Uri("http://dictionary.reference.com/browse/opaque");
            match = ReferenceDotComTemplate.Match(ReferenceDotComBaseUri, referenceDotComUri);

            foreach (string key in match.BoundVariables.Keys)
            {
                Console.WriteLine(String.Format("{0}: {1}", key, match.BoundVariables[key]));
            }
            Console.ReadLine();
        }
    }
}