.Net 的 RestFul Service

關於本文html

這篇文章的目的就是向你們闡述如何在.net framework 4.0中建立RestFul Service而且使用它。web

什麼是web Services,什麼是WCF編程

首先講到的是web Service, 它是一種可以讓客戶端程序在web頁面上經過HTTP協議請求須要數據的部件。咱們能夠用Asp.net建立普通的Web Services而且讓這些Services可以被客戶端程序所調用。安全

其次說到的是Web Services,它是一個編程平臺,它可以經過遵循Simple Object Access Protocol (SOAP)方式來接收或者是發送數據。服務器

而後就是WCF了,它是可以編寫基於service-oriented architecture (SOA)服務的編程模型。經過它,開發人員能夠編寫出跨平臺的,安全的,可靠的解決方案出來。網絡

WCF能夠爲各類各樣的客戶提供集中式的運算服務,客戶能夠調用多個服務,同時,相同的服務也可以被多個用戶所調用。數據結構

在建立咱們的WCF項目以前,咱們最好可以看一下這篇文章:Introduction of Window Communication Foundationless

下面是WebServices和WCF Services的數據比對:分佈式

 

Web Services WCF Services
Web Services可以用來開發基於SOAP的消息發送和接收的應用,這些消息是XML格式的,這些xml格式的消息能夠經過.net Framework 提供的工具類來進行序列化。這種能夠可以自動生成元數據(metadata)來描述Web Services的技術,咱們稱爲: The Web Services Description Language ( WSDL )(注意:WSDL是一種描述WebService服務以及說明如何與Web服務進行通訊的XML語言。) WCF Services可以用來開發基於多種協議格式的應用,SOAP只是其默認的格式。它的消息格式也是使用XML,可是序列化這些xml數據的方式有不少種。它能夠經過WSDL自動的生成可以描述其應用的元數據,同時也可以利用工具來生成。 

對於WCF來講,發送消息不侷限於HTTP方式,TCP或者是其餘的網絡協議也能夠。而且在這些協議中進行切換,也是垂手可得的事兒。它除了可以放到服務器上運行以外,還可以支持宿主寄存,它同時可以很是容易的支持最新的Web Services標準(SOAP 1.2 and WS-*), 
它除了可以以SOAP的方式發送數據,也可以用其餘的方式來進行。
XmlSerializer DataContractSerializer
當Asp.net從服務器發送數據或者是接收客戶端傳來的數據的時候,它是利用XmlSerializer來進行數據的轉換的。 DataContractSerializer代表,有0個或者是多個屬性或者是字段須要被序列化;而DataMemberAttribute 則代表一個指定的屬性或者字段須要被序列化。DataContractAttribute能夠被應用到具備Public 或者是Private的屬性或者字段中,全部被標記上DataContractAttribute的屬性或者字段,在WCF中被稱做是數據契約(DataContracts),他們將會被DataContractSerializer序列化成XML結構。
System.Xml.Serialization下的XmlSerializer類及其各類特性,可讓各類.net framework 類型轉換成xml結構,它對XML提供了很是好的控制。 DataContractSerializer,DataContractAttribute,DataMemberAttribute對XML提供了頗有限的控制,因此,你只可以經過命名空間去甄別。你能夠利用DataContractSerializer去操控除了xml以外的各類數據結構,這種沒有添加過多限制的操做,可以讓DataContractSerializer更易於操控。
和DataContractSerializer相比,它的性能差一些 DataContractSerializer性能好一些,性能通常會提高10%左右
XmlSerializer不會預知應該或者是不該該包含什麼字段或者是屬性到XML中。 利用DataMemberAttribute,在DataContractSerializer進行序列化的時候,能夠很是明確地知道數據結構。
XmlSerializer只可以將Public類型的成員進行序列化。 DataContractSerializer不會類型成員的屬性進行檢測。
只有繼承自IEnumerable或者是ICollection接口的集合類型纔可以被序列化成XML。 DataContractSerializer能夠將任何.net類型轉換成xml結構.
繼承自IDictionary接口的類,好比說Hashtable,是不可以被序列化成XML的。 繼承自IDictionary接口的類,好比說Hashtable,可以被序列化成XML。
XmlSerializer不支持版本控制 DataContractSerializer支持版本控制。
XmlSerializer對序列化的xml語義結構基本相同。 DataContractSerializer序列化爲xml的時候,需提供明確的命名空間。

 

什麼是REST和 RESTFul?ide

Representational State Transfer(REST)在2000年被Roy Fielding提出。它是利用World Wide Web的相關技術以及協議來構建大規模的網絡軟件的構架方式。它意在說明,數據資源是能夠被定義,被髮布的,尤爲是在消息交換的簡易性和可擴展性方面。

早在2000年的時候, 制定HTTP規範的首席做者之一,Roy Fielding,寫了一篇名爲「Architectural Styles and the Design of Network-based Software Architectures.」的博士論文,在文中,做者如是說。

REST,一種可以構建分佈式超媒體驅動程序的構架方式,它包括經過利用標準的HTTP Verbs(GETPOSTPUT, and DELETE)來定義資源,從而構建Resource-Oriented Architecture (ROA)程序。這種構建能夠經過Uniform Resource Identifier(URI)發佈給使用者。

REST 是不綁定任何技術或者是平臺的。它只是用來把工做設計成能像Web那樣。人們常常把這種方式定義爲「RESTFul Services」,可是事實上,利用REST 構架方式開發的WCF Services,也可以被稱做是RESTFul Services。

WCF Services RESTFul Services
各自的網絡協議之間,須要建立端點。 能夠經過HTTP Web方式來進行數據的收發操做。
須要Remote Procedural Call(RPC)的支持 須要定義基於HTTP的統一接口
客戶端須要添加對服務端的引用 不須要客戶端添加對服務端的引用

關於案例代碼?

在WCF 中,REST,其實就是一系列的.net framework 類和visual studio的一些特性和模板,經過這些東西,用戶能夠建立而且使用基於REST方式的WCF服務。這些服務是須要.net 3.5 SP1中的WCF Web編程模型支持的。在後面的附件中,已經包含了全部的源代碼,示例,以及單元測試。

建立基礎的RESTFul Service

步驟一:

利用Visual Studio 2010建立一個新的WCF 項目:

QQ截圖20131022141221

步驟二:

刪掉自帶的IService1.cs以及Service1.svc文件,同時建立如下兩個文件:IRESTService.cs &RESTService.cs.

QQ截圖20131022141505

步驟三:

在IService.cs文件中建立Person 實體類以及一些簡單的屬性,同時加上DataContract & DataMember特性以便於DataContractSerialization進行序列化:

[DataContract]
public class Person
{
    [DataMember(order=1)]
    public string ID;
    [DataMember(order=2)]
    public string Name;
    [DataMember(order=3)]
    public string Age;
    [DataMember(order=4)]
    public string Address;

} 注意,必定要加上Order=*,不然,客戶端向服務端添加數據的時候,會出現某些數據字段沒有值的狀況。

步驟四:

在IRESTService接口文件中建立方法,利用ServiceContract和OperationContrat進行修飾:

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace RESTFulDaemon
{
    [ServiceContract]
    public interface IRestSerivce
    {
        //POST operation
        [OperationContract]
        [WebInvoke(
             UriTemplate = ""
            ,ResponseFormat = WebMessageFormat.Xml
            ,RequestFormat = WebMessageFormat.Xml
            ,Method = "POST"
            )]
        Person CreatePerson(Person createPerson);

        //Get Operation
        [OperationContract]
        [WebGet(
            UriTemplate = ""
          , ResponseFormat = WebMessageFormat.Xml
          , RequestFormat = WebMessageFormat.Xml
            )]
        List<Person> GetAllPerson();

        [OperationContract]
        [WebGet(
            UriTemplate = "{id}"
          , ResponseFormat = WebMessageFormat.Json
          , RequestFormat = WebMessageFormat.Json
            )]
        Person GetAPerson(string id);

        //PUT Operation
        [OperationContract]
        [WebInvoke(
            UriTemplate = ""
          , ResponseFormat = WebMessageFormat.Json
          , RequestFormat = WebMessageFormat.Json
          , Method = "PUT"
          )]
        string UpdatePerson(Person updatePerson);

        //DELETE Operation
        [OperationContract]
        [WebInvoke(
              UriTemplate = ""
            , ResponseFormat = WebMessageFormat.Json
            , Method = "DELETE"
            )]
        string DeletePerson(string id);
    }
}
複製代碼

代碼中,能夠利用JSON來組織數據,也能夠利用XML來組織數據 

步驟五:
WebGet 操做只是從服務端接收數據的操做,它能夠被REST編程模型所調用。它會和OperationContact一塊兒被應用到方法上,而且會帶有UriTemplate屬性和HTTP中的Get操做。
WebInvoke 能夠引起服務端操做,它能夠被REST編程模型所調用。當它具備UriTemplate定義而且擁有傳輸方式(好比, HTTP , , or ),同時和OperationContact放在一塊的時候,就代表當前方法支持的是不一樣類型的HTTP傳輸方式。默認是POST方式。
POSTPUTDELETE
下面 是具體說明:
Person CreatePerson(Person createPerson);
//It is basically insert operation, so WebInvoke HTTP POST is used
 
List<person> GetAllPerson();
Person GetAPerson(string id);
//These two methods retrieve the information, so WebGet (HTTP Get) is used
 
 Person UpdatePerson(Person updatePerson);
//This method updates the available information, so WebInvoke HTTP PUT is used
 
void DeletePerson(string id);
//This method deletes the available information, 
//so WebInvoke HTTP DELETE is used
 
步驟六:
實如今RESTService類中實現IRESTService接口:
複製代碼
public class RESTService:IRestSerivce
    {
        List<Person> persons = new List<Person>();
        private static int tCount = 0;
        public Person CreatePerson(Person person)
        {
            tCount++;
            person.ID = tCount.ToString();
            persons.Add(person);
            return person;
        }
        public List<Person> GetAllPerson()
        {
            return persons.ToList();
        }
        public Person GetAPerson(string id)
        {
            return persons.FirstOrDefault(e => e.ID.Equals(id));
        }
        public string UpdatePerson(Person updatePerson)
        {
            Person p = persons.FirstOrDefault(e => e.ID.Equals(updatePerson.ID));
            p.Name = updatePerson.Name+"[updated]";
            p.Age = updatePerson.Age+"[updated]";
            p.Address = updatePerson.Address+"[updated]";
            return "Updated success";
        }
        public string DeletePerson(string id)
        {
            persons.RemoveAll(e => e.ID.Equals(id));
            return "success";
        }
    }
複製代碼

 

步驟七:
爲了讓這個服務可以在ASP.NET兼容模式下運行,咱們須要利用AspNetCompatibilityRequirements特性來修飾RESTService類:
 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class RESTService:IRestSerivce
    {
       //Code here
    }

 

因此目前的代碼以下:
複製代碼
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Activation;
using System.ServiceModel;
using System;

namespace RESTFulDaemon
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class RESTService:IRestSerivce
    {
        List<Person> persons = new List<Person>();
        private static int tCount = 0;
        public Person CreatePerson(Person person)
        {
            tCount++;
            person.ID = tCount.ToString();
            persons.Add(person);
            return person;
        }
        public List<Person> GetAllPerson()
        {
            return persons.ToList();
        }
        public Person GetAPerson(string id)
        {
            return persons.FirstOrDefault(e => e.ID.Equals(id));
        }
        public string UpdatePerson(Person updatePerson)
        {
            Person p = persons.FirstOrDefault(e => e.ID.Equals(updatePerson.ID));
            p.Name = updatePerson.Name+"[updated]";
            p.Age = updatePerson.Age+"[updated]";
            p.Address = updatePerson.Address+"[updated]";
            return "Updated success";
        }
        public string DeletePerson(string id)
        {
            persons.RemoveAll(e => e.ID.Equals(id));
            return "success";
        }
    }
}
複製代碼

 

在上述的類中,類前面被打上了ServiceBehavior特性,主要是用來講明這服務端只會存在這個類的一個實例.
 
步驟八:
若是要使用這個RESTFul Service應用,那麼這個服務就必須得被寄宿.因此咱們必須作以下的更改才能讓RESTService跑起來.
在Web.config文件中,移除掉<system.servicemodel>下面的全部代碼,而且加入以下的新的代碼:
<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
    </serviceHostingEnvironment>
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"></standardEndpoint>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

其中,<serviceHostingEnvironment>標記用於制定當前應用將運行在Asp.net兼容模式下.

<standardEndpoints> 標記用於爲RESTFul應用獲取WebHelp.

而後,在Global.asax文件中,咱們須要在Application_Start事件中添加以下代碼:

RouteTable.Routes.Add(new ServiceRoute("RestService", new WebServiceHostFactory(), typeof(RESTSerivce))); 
 
步驟九:
運行這個應用:
咱們能夠看到以下的頁面:
QQ截圖20131022144957
當運行 http://localhost:****/RestService/Help的時候,咱們能夠看到以下頁面:
QQ截圖20131022145015
 
如何使用RESTFul Service呢?

客戶端編程

這裏我先貼出客戶端代碼:

  View Code

下面是利用WPF寫的Client程序,當點擊「建立用戶」按鈕的時候,顯示的結果:

當點擊「獲取全部用戶」的時候,會把全部用戶的ID號給獲取到:
當點擊「獲取某個用戶」按鈕時的結果(2號用戶信息被獲取):
當點擊「更新某個用戶」按鈕時的結果(3號用戶信息被更新):

當點擊「刪除某個用戶」按鈕時候的顯示結果(4號用戶被刪除):

 

Client端的顯示效果以下:

源碼下載

 Click here to get source code

特別說明:本文轉載自http://www.cnblogs.com/scy251147/p/3382436.html,可是文中的示例可以充分展現在客戶端的CRUD的過程。
 
阿里巴巴早餐計劃,我國每一年都有2000萬人得胃病,很大一部分緣由是沒有及時吃早餐。阿里計劃每一年發放20億早餐補貼來鼓勵您及時吃早餐。 支付寶首頁搜索547567984。 領取補貼,用於早餐消費等。天天都能領喔
相關文章
相關標籤/搜索