WCF(12)之WCF中Rest服務入門

一、引言

   要將Rest與.NET Framework 3.0配合使用,還需要構建基礎架構的一些部件。在.NET Framework 3.5中,WCF在System.ServiceModel.Web組件中新增了編程模型和這些基礎架構部件。

  新編程模型有兩個主要的新屬性:WebGetAttribute和WebInvokeAttribute,還有一個URI模板機制,幫助你聲明每種方法響應使用的URI和動詞。.NET Framework還提供了一個新的綁定(WebHttpBinding)和新的行爲(WebHttpBehavior),此外,還提供了WebServiceHost和WebServiceHostFactory類來對Rest服務進行支持。下面讓我們具體看看WCF目前對Rest服務的支持和實現。

二、REST服務是什麼

  對於這個問題,百度下有很多答案,這裏給出百度百科中一個詳細介紹的鏈接:Rest服務。我的理解的Rest服務是:以前我們都是把WCF服務抽象爲操作的概念,而Rest最早是由Roy Thomas Fielding 在他的博士論文(“體系結構風格和基於網絡軟件體系的設計”)中提出的。Rest服務是將服務抽象爲資源,每個資源都有一個唯一的統一資源標識符(URI),我們不再是通過調用操作的方式與服務進行交互了,而是通過HTTP標準動詞(GET、POST、PUT和DELETE)的統一接口來完成。總之一句話概括,Rest服務換了一種思維方式,把服務也當成一種資源,通過Get、Post、Put和Delete這些HTTP動詞來進行交互。這樣,問題就來了,Rest服務具有什麼好處呢?即我們爲什麼要去關注Rest和實現它呢?

  Rest優勢就在於其使用極其簡單,Rest服務要求很少的編碼工作量,可以減少很多不必要的工作。Rest服務主要有以下優點:

  • 無需引入SOAP消息傳輸層,輕量級和高效率的HTTP格式可直接被應用。

  • 可以輕易地在任何編程語言中實現,尤其是在JS中。使用SOAP的服務與JS交互非常繁瑣,而使用Rest服務與JS交互非常簡單。

  • 可以不使用任何編程語言就能訪問服務,而只需要使用Web瀏覽器即可。

  • 更好的性能和緩存支持。使用Rest服務可以改善響應時間和改善用戶體驗。

  • 可擴展性和無狀態性。Rest服務基於HTTP協議,每個請求都是獨立的,一旦被調用,服務器不保留任何會話,這樣可以更具響應性,通過減少通訊狀態的維護工作來提供服務的可擴展性。

三、WXF和Asp.net Web API的比較

   WCF是微軟爲生成面向服務的應用程序而提供的統一編程模型。Asp.net Web API 是一個用來方便生成HTTP服務的框架,這些服務可供廣泛的客戶端訪問,包括瀏覽器和移動設備。Asp.net Web API用於在.NET平臺上生成Restful應用程序的理想平臺。到這裏問題又來了,Rest服務與SOAP服務的區別又是什麼呢?

  Rest相對於SOAP服務使用更加簡單,對於開發者來說,學習成本較低,而SOAP作爲一種古老的Web服務技術,近期內還不回退出歷史舞臺,而且隨着SOAP 1.2的出現,SOAP 1.1中的一些缺點已得到改進。

  REST目前只基於HTTP和HTTPS協議,而SOAP可支持任何傳輸協議,包括HTTP/HTTPS、TCP、SMTP等協議。另外Rest服務除了能使用XML作爲數據承載外,還有JSON,RSS和ATOM形式。

  Rest與SOAP對應的比較如下所示:

  1. SOAP是一種工業標準,面對的應用需求時RPC(遠程過程調用),而Rest面對的應用需求是分佈式Web系統。

  2. Rest服務強調數據,請求和響應消息都是數據的封裝,而SOAP服務更強調接口,SOAP消息封裝的是過程調用。Rest是面向資源的,而SOAP是面向接口的。

  3. Rest架構下,HTTP是承載協議,也是應用協議,而SOAP架構下,HTTP只是承載協議,SOAP纔是應用協議。

  那在什麼情況下使用Rest,什麼情況下使用SOAP呢?這要看具體的實際情況。具體應用場景如下所示:

  • 遠程調用用SOAP。如果服務是作爲一種功能提供,客戶端調用服務是爲了執行一個功能,用SOAP,比如常見的需求是認證授權。而數據服務用Rest。

  • 要更多的考慮非功能需求時使用SOAP,如需考慮安全、傳輸和協議等需求的情況下。

  • 低帶寬、客戶端的處理能力受限的場合可以考慮使用Rest。如在PDA或手機上消費服務。

  介紹了Rest與SOAP的區別之後,讓我們回到WCF與Asp.net Web API的比較上來,具體兩者功能之間的對比如下圖所示:

  使用 WCF 可創建可靠、安全的 Web 服務,這些服務可通過各種傳輸方式來訪問。 使用 ASP.NET Web API 可創建基於 HTTP 的服務,這些服務可從各種客戶端來訪問。 如果要創建和設計新的 REST 樣式服務,請使用 ASP.NET Web API。 雖然 WCF 針對編寫 REST 樣式服務提供了一些支持,但 ASP.NET Web API 中的 REST 支持更加完整,並且,所有將來的 REST 功能改進都將在 ASP.NET Web API 中進行。

四、WCF中實現Rest服務

   WCF 3.5中對Rest服務也做了支持,主要提供了WebHttpBinding來對Rest進行支持,下面我們通過一個具體的實例來看看如何在WCF中實現一個Rest服務。我們還是按照之前三個步驟來創建該實例。

  第一步:創建Rest服務接口和實現。具體的實現代碼如下所示。

  服務契約代碼如下所示:

 


 

1 [ServiceContract(Namespace ="http://www.cnblogs.com/zhili/")]
2 public interface IEmployees
3 {
4 // 契約操作不再使用操作契約的方式來標識,而是使用WebGetAttribute特性來標識,從而表明該服務是Rest服務
5 [WebGet(UriTemplate = "all")]
6 IEnumerable<Employee> GetAll();
7
8 [WebGet(UriTemplate = "{id}")]
9 Employee Get(string id);
10
11 [WebInvoke(UriTemplate="/", Method="PUT")]
12 void Create(Employee employee);
13
14 [WebInvoke(UriTemplate = "/", Method = "POST")]
15 void Update(Employee employee);
16
17 [WebInvoke(UriTemplate = "/", Method = "DELETE")]
18 void Delete(string id);
19 }
20
21 [DataContract(Namespace = "http://www.cnblogs.com.zhili/")]
22 public class Employee
23 {
24 [DataMember]
25 public string Id { get; set; }
26
27 [DataMember]
28 public string Name { get; set; }
29
30 [DataMember]
31 public string Department { get; set; }
32
33 [DataMember]
34 public string Grade { get; set; }
35
36 public override string ToString()
37 {
38 return string.Format("ID: {0,-5}姓名:{1,-5}部門:{2,-5}級別:{3}",Id, Name, Department, Grade);
39 }
40 }

 

  從上面代碼可以看出,Rest服務不再使用OperactionContract的方式來標識操作了,此時在Rest架構下,每個操作都被當做一種資源對待,所以這裏的操作使用了WebGetAttribute特性和WebInvokeAttribute來標識。下面具體看看契約的具體實現,即Rest服務的實現代碼。

 


 

1 namespace WCFContractAndService
2 {
3 public class EmployeesService : IEmployees
4 {
5 private static IList<Employee> employees = new List<Employee>
6 {
7 new Employee{ Id = "0001", Name = "LearningHard", Department = "開發部",Grade = "G6"},
8 new Employee{Id = "0002", Name = "張三", Department = "QA", Grade = "G5"}
9 };
10
11 public Employee Get(string id)
12 {
13 Employee employee = employees.FirstOrDefault(e => e.Id == id);
14 if (null == employee)
15 {
16 WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
17 }
18 return employee;
19 }
20
21 public IEnumerable<Employee> GetAll()
22 {
23 return employees;
24 }
25
26 public void Create(Employee employee)
27 {
28 employees.Add(employee);
29 }
30
31
32 public void Update(Employee emp)
33 {
34 this.Delete(emp.Id);
35 employees.Add(emp);
36 }
37
38 public void Delete(string id)
39 {
40 Employee employee = this.Get(id);
41 if (null != employee)
42 {
43 employees.Remove(employee);
44 }
45 }
46 }
47 }

 

  第二步:實現Rest服務宿主。這裏還是使用控制檯程序來作爲宿主程序,主要的實現代碼如下所示:

 


 

namespace RestServiceHost
{
class Program
{
static void Main(string[] args)
{
// Rest服務使用WebServiceHost類來爲服務提供宿主
using (WebServiceHost webHost = new WebServiceHost(typeof(EmployeesService)))
{
webHost.Opened += delegate
{
Console.WriteLine("Rest Employee Service 開啓成功!");
};

webHost.Open();
Console.Read();
}
}
}
}

 

  對應的配置文件內容如下所示:

 


 

<configuration>
<system.serviceModel>
<services>
<service name="WCFContractAndService.EmployeesService">
<!--這裏Rest服務只能使用WebHttpBinding來作爲綁定-->
<endpoint address="http://localhost:9003/employeeService"
binding="webHttpBinding" contract="RestContract.IEmployees"/>
</service>
</services>
</system.serviceModel>
</configuration>

 

  第三步:實現Rest服務調用客戶端。這裏通過通道工廠的方式來創建代理對象的,具體的實現代碼如下所示:

 


 

1 namespace WCFClient
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 using (ChannelFactory<IEmployees> channelFactory = new ChannelFactory<IEmployees>("employeeService"))
8 {
9 // 創建代理類
10 IEmployees proxy = channelFactory.CreateChannel();
11
12 Console.WriteLine("所有員工信息:");
13
14 // 通過代理類來對Rest服務進行操作
15 Array.ForEach<Employee>(proxy.GetAll().ToArray(), emp => Console.WriteLine(emp.ToString()));
16
17 Console.WriteLine("\n添加一個新員工{0003}:");
18 proxy.Create(new Employee
19 {
20 Id = "0003", Name="李四", Department="財務部", Grade="G7"
21 });
22
23 Array.ForEach<Employee>(proxy.GetAll().ToArray(), emp => Console.WriteLine(emp.ToString()));
24
25 Console.WriteLine("\n修改員工(0003)信息:");
26 proxy.Update(new Employee
27 {
28 Id = "0003", Name="李四", Department = "銷售部", Grade ="G8"
29 });
30 Array.ForEach<Employee>(proxy.GetAll().ToArray(), emp => Console.WriteLine(emp.ToString()));
31 Console.WriteLine("\n刪除員工(0002)信息:");
32 proxy.Delete("0002");
33 Array.ForEach<Employee>(proxy.GetAll().ToArray(), emp => Console.WriteLine(emp.ToString()));
34
35 Console.Read();
36 }
37 }
38 }
39 }

 

  客戶端對應的配置文件內容如下所示:

 


 

<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint name="employeeService" address="http://localhost:9003/employeeService" binding="webHttpBinding" behaviorConfiguration="webBehavior" contract="RestContract.IEmployees">

</endpoint>
</client>
</system.serviceModel>
</configuration>

 

  經過上面的三步,Rest服務的構建工作就完成了,下面看看該程序的運行結果。

  首先以管理員權限運行服務宿主程序,運行成功後的結果如下圖所示:

  然後再運行客戶端程序,運行成功後的結果如下圖所示:

五、總結

   到這裏,本文要分享的內容就結束了,同時這也是WCF系列的最後一篇博文。WCF主要通過提供幾個新的API來對Rest服務的實現,這裏包括WebHttpBinding類、WebGetAttribute、WebInvokeAttribute特性和WebServiceHost類等。

 

轉自:https://www.cnblogs.com/zhili/p/MSMQ.html,作者:Learning hard。

如有侵權,請聯繫我刪除!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章