本文基於 Visual Studio 2008 預發布版本,資訊可能變更。涵蓋 HTTP 訊息基礎、URI 資訊嵌入、WCF 與 HTTP 整合、RSS/ATOM 整合應用。技術棧:Windows Communication Foundation。
HTTP 是 Web 的傳輸機制,採用請求/回應訊息交換模式 (MEP)。核心動詞:GET、POST、PUT、DELETE。
POST /myservice/PostAlbum HTTP 1.1
HOST: www.cloudsample.net
<albumInfo><albumId>15</albumId></albumInfo>
轉換為 GET:
GET /myservice/GetAlbum/15 HTTP 1.1
HOST: www.cloudsamples.net
URI 即負載,訊息更小、傳輸更快,且利於 Proxy 與瀏覽器快取。GET 代表請求資源,資源通常不變。
DELETE:關聯刪減性狀態變更,但具體動作未定義PUT:關聯增加性狀態變更,具體情況因應用而異應用程式利用 URI 嵌入資訊決定回應資源。範例 URI 模式:
contoso.com/artists/[artist]/[album]
contoso.com/artists/[artist]?album=[album]
1 GET /PictureServices/Feed.svc/picture/Pictures;Bridge.jpg HTTP/1.1
2 Accept: image/gif, image/jpeg, application/xaml+xml, */*
3 Accept-Language: en-us
4 UA-CPU: x86
5 Accept-Encoding: gzip, deflate
6 User-Agent: Mozilla/4.0 ...
7 Host: www.cloudsamples.net
8 Proxy-Connection: Keep-Alive
9 HTTP/1.1 200 OK
10 Content-Type: image/jpeg
11 Server: Microsoft-IIS/7.0
12 X-Powered-By: ASP.NET
13 Date: Sat, 15 Sep 2007 18:57:11 GMT
14 Content-Length: 106333
Accept 標頭指定客戶端可接收格式,Content-Type 描述回應資料格式,雙方協調資料格式的簡單機制。
REST 與 WS-* 非互斥,各有優勢:REST 擅長與簡單客戶端 (瀏覽器) 互動;WS-* 擅長訊息路由至中介層。
新增 System.UriTemplate、System.UriTemplateMatch 類型,簡化 URI 建構與解析:
Uri baseAddress = new Uri("https://localhost:2000");
UriTemplate template = new UriTemplate("{artist}?album={album}");
Uri boundUri = template.BindByPosition(baseAddress, "Northwind", "Overdone");
// 結果: https://localhost:2000/Northwind?album=Overdone
UriTemplateMatch match = template.Match(baseAddress, boundUri);
string bandName = match.BoundVariables["artist"]; // "Northwind"
這兩類型不在 System.ServiceModel 命名空間,可獨立於 WCF 使用。
[ServiceContract]
public interface IPictureService
{
[OperationContract]
[WebGet(UriTemplate = "picture/{pictureId}")]
Stream GetPicture(string pictureId);
[OperationContract]
[WebGet(UriTemplate = "picture/t/{pictureId}")]
Stream GetPictureThumbnail(string pictureId);
[OperationContract]
[WebInvoke(UriTemplate = "update", Method = "POST")]
void UpdatePictureInfo(PictureInfo info);
}
WebGetAttribute:對應 HTTP GET,支援 RequestFormat/ResponseFormat (Xml/Json)WebInvokeAttribute:對應除 GET 外任意 HTTP 動詞,透過 Method 屬性指定public Stream GetPicture(string pictureId)
{
Stream stream = ...; // 取得圖片串流
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
return stream;
}
WebHttpBinding 抽象 Web 風格傳輸;WebHttpBehavior 設定調度篩選器,使用 UriTemplate 匹配與 HTTP 動詞取代 SOAP Action。
ServiceHost host = new ServiceHost(typeof(IPictureContract), new Uri("https://localhost:5000"));
WebHttpBinding binding = new WebHttpBinding();
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IPictureContract), binding, "");
ep.Behaviors.Add(new WebHttpBehavior());
host.Open();
WebServiceHost:自動為所有端點添加 WebHttpBehavior,執行驗證WebServiceHostFactory:適用 IIS 裝載,在 .svc 指令中指定 Factory<%@ ServiceHost Language="C#" Service="PictureService" Factory="System.ServiceModel.Web.WebServiceHostFactory" %>
web.config 無需任何 WCF 相關設定。
整合內容不限於新聞/部落格,可表達任何資料集合。.NET Framework 3.5 完整支援 RSS 2.0、ATOM 1.0 建立與消費,支援擴充,編程模型避免直接處理格式細節。
SyndicationFeed:整合來源中性表現,包含 SyndicationItem 集合SyndicationFeedFormatter<T>:轉換為特定格式,衍生 Rss20FeedFormatter、Atom10FeedFormatter手動建構:
SyndicationFeed feed = new SyndicationFeed();
feed.Title.Text = "The Cybertopian Chronicle";
// 設定其他屬性...
從現有來源載入:
Uri feedUri = new Uri("https://blogs.msdn.com/justinjsmith/atom.xml");
SyndicationFeed feed = SyndicationFeed.Load(feedUri);
Console.WriteLine(feed.Title.Text); // "The Cybertopian Chronicle"
超過 35 個成員,涵蓋項目識別碼、更新時間、發布日期、標題、內容等,支援各種擴充 (Microsoft Simple List Extensions、Yahoo Media RSS、GeoRSS 等)。
SyndicationFeed.Items 為 IEnumerable<SyndicationItem>,利用迭代器特性與 LINQ 高效處理大量項目。
Uri feedUri = new Uri("https://blogs.msdn.com/justinjsmith/atom.xml");
SyndicationFeed feed = SyndicationFeed.Load(feedUri);
Rss20FeedFormatter formatter = new Rss20FeedFormatter(feed);
XmlWriter writer = XmlWriter.Create(Console.Out, null);
formatter.WriteTo(writer);
writer.Flush();
[ServiceKnownType(typeof(Atom10FeedFormatter))]
[ServiceKnownType(typeof(Rss20FeedFormatter))]
[ServiceContract]
interface IPictureService
{
[OperationContract]
[WebGet(UriTemplate = "Pictures?format={format}")]
SyndicationFeedFormatter<SyndicationFeed> Feed(string format);
}
class PictureService : IPictureService
{
public SyndicationFeedFormatter<SyndicationFeed> Feed(string format)
{
SyndicationFeed feed = new SyndicationFeed();
// 加入項目...
if (format.ToLower() == "rss")
return new Rss20FeedFormatter(feed);
return new Atom10FeedFormatter(feed);
}
}
掌握 HTTP 基礎、Web 原則、WCF HTTP 程式設計模型與整合 API,可構建兼容 SOAP/WS-* 企業整合與 Web 風格對外服務的統一平台。範例應用 PictureServices (www.cloudsamples.net/pictureservices) 整合本地檔案、Windows 桌面搜尋、Flickr 圖片來源,提供 RSS/ATOM 訂閱與圖片瀏覽功能。
作者:Justin Smith,Microsoft Web 服務技術專家,專注 WCF 與 BizTalk 服務,著作《Inside Windows Communication Foundation》(Microsoft Press, 2007),部落格:blogs.msdn.com/justinjsmith