跟我一起學WCF(12)——WCF中Rest服務入門


一、引言

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

  新編程模型有兩個主要的新屬性:WebGetAttributeWebInvokeAttribute,還有一個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類等。接下來一篇博文將對本系列做一個總結。

  本文所有源碼:WCFRestService.zip

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM