从.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(); } } }