先來點理論知識,來自 http://www.cnblogs.com/simonchen/articles/2220838.htmlhtml
REST軟件架構是由Roy Thomas Fielding博士2000年在他的論文《Architectural Styles and the Design of Network- based Software Architectures》首次提出的。他提出的理論對後來的Web技術的發展產生了巨大的影響,他是許多重要Web架構標準的設計者,這些標準就是 HTTP、URI等。web
因爲Rest遵照的這些規範,所以Rest架構的特色也很是的明顯:json
既然Rest風格有這些特色,那麼也就具有了許多優勢:瀏覽器
REST架構是針對Web應用而設計的,其目的是爲了下降開發的複雜性,提升系統的可伸縮性。REST提出了以下設計準則:緩存
甩過一遍理論,那麼就趁熱實踐一番吧!安全
按正常步驟新建一個WCF應用,常見的CRUD操做服務器
[ServiceContract] public interface IExampleService { [OperationContract] string GetData(string value); [OperationContract] string AddData(string value); [OperationContract ] string UpdateData(string value); [OperationContract ] string DeleteData(string value); }
那麼rest模式該是如何呢?網絡
[ServiceContract] public interface IExampleService { [OperationContract] [WebGet(UriTemplate = "/Rest/Get/{value}", ResponseFormat = WebMessageFormat.Json)] string GetData(string value); [OperationContract] [WebInvoke(UriTemplate = "/Rest/Add/{value}", Method = "POST")] string AddData(string value); [OperationContract ] [WebInvoke(UriTemplate = "/Rest/Update/{value}", Method = "PUT")] string UpdateData(string value); [OperationContract ] [WebInvoke (UriTemplate="/Rest/Delete/{value}",Method="DELETE")] string DeleteData(string value); }
比較下就很容易看出多加了些標籤,而且也從方法的使用上能夠對應出GET、POST、PUT、DELETE的使用。架構
wcf能夠看元數據,那麼rest也有對應的方式,在web.config中添加以下配置就能夠查看help頁面併發
<services> <service name="RestWCFTest.ExampleService"> <endpoint address="" behaviorConfiguration="HelpBehavior" binding="webHttpBinding" bindingConfiguration="" contract="RestWCFTest.IExampleService" /> </service> </services> <behaviors> <endpointBehaviors> <behavior name="HelpBehavior"> <webHttp helpEnabled="true" /> </behavior> </endpointBehaviors> </behaviors>
help頁面以下
點擊方法進去能夠看見調用方式
咱們的接口實現
public string GetData(string value) { return string.Format("You entered: {0}", value); } public string AddData(string value) { return string.Format("You added: {0}", value); } public string UpdateData(string value) { return string.Format("You updated: {0}", value); } public string DeleteData(string value) { return string.Format("You deleted: {0}", value); }
如今咱們用fiddler來模擬請求測試下
在composer選項裏有模擬請求的功能,very good!咱們先來調用GetData操做,根據參數獲取數據,根據設置的URI模板,「123456」爲匹配
的參數,執行它!
看請求的信息
GET http://localhost/REST4/ExampleService.svc/Rest/Get/123456 HTTP/1.1
User-Agent: Fiddler
Content-type: application/json
Host: localhost
Content-Length: 0
看響應的數據
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 21
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 27 Sep 2013 05:16:52 GMT
"You entered: 123456"
200 OK 調用正常,content-type是json,由於咱們指定的,IIS是7.5,對,個人確是部署在7.5上。。。看結果也是和預期如出一轍,so easy~
可能有同窗會問,這是返回的json數據麼?我也以爲不是,若是在方法標籤上修改成以下
[OperationContract]
[WebGet(UriTemplate = "/Rest/Get/{value}",BodyStyle=WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
string GetData(string value);
多加了個修飾bodystyle,它的功能是對結果進行包裝,包裝後再看返回的結果
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 39
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 27 Sep 2013 06:34:24 GMT
{"GetDataResult":"You entered: 123456"}
果真,被包裝了,它是一個json格式的數據了。
POST
請求
POST http://localhost/REST4/ExampleService.svc/Rest/Add/1234 HTTP/1.1
User-Agent: Fiddler
Content-type: application/json
Host: localhost
Content-Length: 0
響應
HTTP/1.1 200 OK Cache-Control: private Content-Length: 92 Content-Type: application/xml; charset=utf-8 Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Fri, 27 Sep 2013 05:06:41 GMT <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You added: 1234</string>
這個時候咱們沒有指定返回的格式,默認爲XML。
PUT
請求
PUT http://localhost/REST4/ExampleService.svc/Rest/Update/123 HTTP/1.1
User-Agent: Fiddler
Content-type: application/json
Host: localhost
Content-Length: 0
響應
HTTP/1.1 200 OK Cache-Control: private Content-Length: 93 Content-Type: application/xml; charset=utf-8 Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Fri, 27 Sep 2013 05:23:04 GMT <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You updated: 123</string>
DELETE
請求
DELETE http://localhost/REST4/ExampleService.svc/Rest/Delete/123 HTTP/1.1
User-Agent: Fiddler
Content-type: application/json
Host: localhost
Content-Length: 0
響應
HTTP/1.1 200 OK Cache-Control: private Content-Length: 93 Content-Type: application/xml; charset=utf-8 Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Fri, 27 Sep 2013 05:14:56 GMT <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You deleted: 123</string>
有同窗可能DELETE請求發出去沒反應(IIS 7.5),請在web.config里加上如下節點
<system.webServer> <modules runAllManagedModulesForAllRequests="true"> <remove name="WebDAVModule" /> </modules> <handlers> <remove name="WebDAV" /> </handlers> </system.webServer>
至此通常的傳參狀況就是如此了,下面列舉一些其它傳參狀況
[OperationContract] [WebGet(UriTemplate = "/Rest/GetList2/", ResponseFormat = WebMessageFormat.Json)] List<ExampleData> GetDataLs2(); [OperationContract] [WebInvoke(UriTemplate = "/Rest/AddLs3", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "POST")] List<ExampleData> AddDataLs3(List<ExampleData> datas); [OperationContract] [WebInvoke(UriTemplate = "/Rest/AddLs4", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "POST")] List<ExampleData> AddDataLs4(List<ExampleData> datas1, List<ExampleData> datas2);
實體
public class ExampleData { public string Name { get; set; } public string Age { get; set; } }
接口實現
public List<ExampleData> GetDataLs2() { List<ExampleData> result = new List<ExampleData> { new ExampleData{ Name="張三", Age="20"} ,new ExampleData {Name="李四",Age="21"} ,new ExampleData {Name="王五",Age="30"} }; return result; } public List<ExampleData> AddDataLs3(List<ExampleData> datas) { return datas; } public List<ExampleData> AddDataLs4(List<ExampleData> datas1, List<ExampleData> datas2) { List<ExampleData> result = new List<ExampleData>(); result.AddRange(datas1); result.AddRange(datas2); return result; }
咱們看到有獲取實體集合了,還有傳參的時候也是實體集合了
首先看看獲取集合的狀況
請求
GET http://localhost/REST4/ExampleService.svc/Rest/GetList2/ HTTP/1.1
User-Agent: Fiddler
Content-type: application/json
Host: localhost
Content-Length: 0
響應
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 88
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 27 Sep 2013 05:21:52 GMT
[{"Age":"20","Name":"張三"},{"Age":"21","Name":"李四"},{"Age":"30","Name":"王五"}]
嗯,返回的格式不錯。
看看怎樣作新增操做的
AddDataLs3
請求
POST http://localhost/REST4/ExampleService.svc/Rest/AddLs3 HTTP/1.1
User-Agent: Fiddler
Content-type: application/json
Host: localhost
Content-Length: 41
{"datas":[{"Name":"xiaohua","Age":"13"}]}
這時候咱們會注意到,多了request body了,而且datas就是參數名
響應
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 52
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 27 Sep 2013 06:59:55 GMT
{"AddDataLs3Result":[{"Age":"13","Name":"xiaohua"}]}
被包裝了的數據。
AddDataLs4
請求
POST http://localhost/REST4/ExampleService.svc/Rest/AddLs4 HTTP/1.1
User-Agent: Fiddler
Content-type: application/json
Host: localhost
Content-Length: 78
{"datas1":[{"Name":"xiaohua","Age":"13"}],"datas2":[{"Name":"li","Age":"13"}]}
響應
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 77
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 27 Sep 2013 07:02:58 GMT
{"AddDataLs4Result":[{"Age":"13","Name":"xiaohua"},{"Age":"13","Name":"li"}]}
面對茫茫多的CRUD的時候,咱們也許會顯得不耐煩,由於每一個操做都去寫方法,真是煩躁,不妨能夠試下以下的方式
[OperationContract] [WebInvoke(UriTemplate = "/Rest/*", Method = "*", ResponseFormat = WebMessageFormat.Json)] string ExecuteData();
用星號來匹配全部的請求,讓程序區識別請求究竟是GET、POST、PUT仍是DELETE
實現
public string ExecuteData() { var request = WebOperationContext.Current.IncomingRequest; var method = request.Method; var args = request.UriTemplateMatch.WildcardPathSegments; switch (method) { case "POST": return "POST..."; case "DELETE": return "DELETE..."; case "PUT": return "UPDATE..."; default: return "GET..."; } }
嗯,不知不覺就貼了這麼多代碼了,其實我字沒寫多少,今天就到這吧,算是入門了吧。
以上例子全部源碼下載