這幾天思考REST 架構下POST複雜資料類型的問題查了寫資料,以及通過與WCF 大牛------Frank Xulei進行了一番交流對REST有了一些進一步的認識。本篇作為:1、REST與SOA兩種架構下WCF的異同比較 2、通過HTTP協議標準動作使用REST WCF 服務 這兩篇的一個補充。
起因是這樣的:在SOA架構下,一般都是通過定義服務契約的方式最終通過WSDL將中繼資料對外發布,以供調用者使用。也就是說在SOA中,通過服務契約定義向外公布服務對外提供的操作。如果先學習SOA,然後接觸REST,可能會在使用REST的時候會沿用SOA下的一些習慣。我在進行REST架構下的WCF學習過程中也是沿用了這一思路:先定義服務介面,然後實現服務供消費者使用。
後來仔細想了想REST架構的原則,通過定義契約介面的方式固然可行,並且在前幾節中也做了實現的說明。但真的有必要這樣做嗎。?
由於REST架構下的服務通過公用的連接器介面(主要是指GET,POST,PUT,DELETE)對服務進行訪問。用戶端只需知道服務的統一資源標識---URI(Uniform Resources Identifier)以及相應的HTTP動作就行了(可以通過REST 架構下的協助頁面,即HTTP://ServiceAddress/help就能知道各個服務如何使用)。因此在REST架構下,WCF服務無需向用戶端暴露中繼資料資訊。這也是REST架構下,WCF不需要定義服務契約的原因。由於沒有中繼資料資訊,因此REST WCF服務也不能通過添加引用的方式使用。
小結:
1、REST 架構下無需給服務定義服務契約(非必須,若定義也行)。
2、REST 架構下的服務不能添加引用的方式使用。
在物件導向語言中,操作一般都針對對象而言。REST中如何POST自訂類型。?下面說說REST架構下,複雜資料類型的POST操作。(代碼下載)
服務的實現:
[OperationContract]
[WebInvoke(UriTemplate = "Person/Post")]
public string Post(Person person)
{
return person.Name + person.Tel;
}
調用方式如下:
static void InvokeMutiType()
{
using (MemoryStream ms = new MemoryStream())
{
WebClient webClient = new WebClient();
Person person = new Person { Name = "tyb", Tel = "01021234568" };
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));
xmlSerializer.Serialize(ms, person);
ms.Seek(0, SeekOrigin.Begin);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(ms);
webClient.Headers[HttpRequestHeader.ContentType] = "application/xml";
try
{
string str = webClient.UploadString("http://localhost:6012/RestService.svc/Person/Post", "POST" , xmlDocument.InnerXml);
Console.WriteLine("接收到的資料為:{0}", str);
}
catch (WebException exception)
{
Console.WriteLine(exception.Status);
}
}
}
調用結果如:
由上可知:對自訂類型資料採用POST操作時,需要通過序列話然後發送給服務端。服務端在接受到資料後能自動對應到自訂類型上。
以上通過WebClient發送的,也可以通過HttpWebRequest與HttpWebResponse來實現。