關於本文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(GET
, POST
, PUT
, 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 項目:
步驟二:
刪掉自帶的IService1.cs以及Service1.svc文件,同時建立如下兩個文件:IRESTService.cs &RESTService.cs.
步驟三:
在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
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"; } }
[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"; } } }
<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)));
客戶端編程
這裏我先貼出客戶端代碼:
下面是利用WPF寫的Client程序,當點擊「建立用戶」按鈕的時候,顯示的結果:
當點擊「刪除某個用戶」按鈕時候的顯示結果(4號用戶被刪除):
Client端的顯示效果以下:
源碼下載