WCF简单教程(11) REST调用

第十一篇:REST调用

上篇写的是Ajax调用WCF,今天写一篇如何以REST方式调用WCF服务。不知道REST是什么的同学,可以去google一下。对某些类型的应用,REST还是相当不错的方式,所以专门写一篇来说明一下开发方法。

老规矩,上代码,直接在代码注释里讲解。


1、服务端:

服务契约,我们定义CRUD4个方法(增查改删),对应HTTP METHOD分别为PUT/GET/POST/DELETE:

   
   
   
   
  1. using System;

  2. using System.ServiceModel;

  3. using System.ServiceModel.Web;   //这个命名空间要求引入System.ServiceModel.Web.dll

  4. namespace Server

  5. {

  6.    [ServiceContract(Namespace = "WCF.Demo")]

  7. publicinterface IData

  8.    {

  9. //WebInvoke中标明REST的相关属性,以这个方法为例,调用的Url是 ..../Data/key/data,HTTP方法是PUT,响应为Json格式(也可以换成xml)

  10. //这样如果客户端用PUT方法访问 ..../Data/1/100,就会映射到CreateData方法上来,并且传入key=1,data=100

  11.        [OperationContract]

  12.        [WebInvoke(UriTemplate = "Data/{key}/{data}", Method = "PUT", ResponseFormat = WebMessageFormat.Json)]

  13. void CreateData(string key, string data);

  14.        [OperationContract]

  15.        [WebInvoke(UriTemplate = "Data/{key}", Method = "GET", ResponseFormat = WebMessageFormat.Json)]

  16. string RetrieveData(string key);

  17.        [OperationContract]

  18.        [WebInvoke(UriTemplate = "Data/{key}/{data}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]

  19. void UpdateData(string key, string data);

  20.        [OperationContract]

  21.        [WebInvoke(UriTemplate = "Data/{key}", Method = "DELETE", ResponseFormat = WebMessageFormat.Json)]

  22. void DeleteData(string key);

  23.    }

  24. }

然后是实现类,这个简单,没什么可说的。

   
   
   
   
  1. using System;

  2. using System.Collections.Generic;

  3. using System.ServiceModel;

  4. namespace Server

  5. {

  6. //这个例子中用了Single Instance模式,这样m_DataDict的值才能保留住

  7.    [ServiceInstanceContextMode = InstanceContextMode.Single)]

  8. publicclass DataProvider : IData

  9.    {

  10. private Dictionary<string, string> m_DataDict = new Dictionary<string, string>();

  11. publicvoid CreateData(string key, string data)

  12.        {

  13.            m_DataDict[key] = data;

  14.        }

  15. publicstring RetrieveData(string key)

  16.        {

  17. return m_DataDict.ContainsKey(key) ? m_DataDict[key] : "NOT FOUND";

  18.        }

  19. publicvoid UpdateData(string key, string data)

  20.        {

  21.            m_DataDict[key] = data;

  22.        }

  23. publicvoid DeleteData(string key)

  24.        {

  25.            m_DataDict.Remove(key);

  26.        }

  27.    }

  28. }

配置文件最关键了,注意里面绿色的注释部分:

   
   
   
   
  1. <?xmlversion="1.0"encoding="utf-8"?>

  2. <configuration>

  3. <system.serviceModel>

  4. <services>

  5. <servicename="Server.DataProvider">

  6. <!--必须使用webHttpBinding,而且要定义此endpoint的behaviorConfiguration(见后)-->

  7. <endpointaddress=""binding="webHttpBinding"contract="Server.IData"behaviorConfiguration="restBehavior"/>

  8. <host>

  9. <baseAddresses>

  10. <addbaseAddress="http://localhost:8080/wcf"/>

  11. </baseAddresses>

  12. </host>

  13. </service>

  14. </services>

  15. <behaviors>

  16. <!--定义endpoint的behavior,webHttp节点表示启用web方式访问,这对REST是非常关键的-->

  17. <endpointBehaviors>

  18. <behaviorname="restBehavior">

  19. <webHttp/>

  20. </behavior>

  21. </endpointBehaviors>

  22. </behaviors>

  23. </system.serviceModel>

  24. </configuration>

最后发布服务,没什么特殊的,和以前一样:

   
   
   
   
  1. using System;

  2. using System.ServiceModel;

  3. namespace Server

  4. {

  5. class Program

  6.    {

  7. staticvoid Main(string[] args)

  8.        {

  9. using(ServiceHost host = new ServiceHost(typeof(Server.DataProvider)))

  10.            {

  11.                host.Open();

  12.                Console.WriteLine("Running ...");

  13.                Console.ReadKey();

  14.                host.Close();

  15.            }

  16.        }

  17.    }

  18. }

这个服务端没有用IIS做HOST,直接用自己的进程做的宿主(当然了,本质还是http.sys在工作)。



2、客户端

我们这回要用REST形式访问服务端,所以不是普通意义上的WCF客户端了,再也用不着那么麻烦的写配置文件创建Channel或者代理了。

   
   
   
   
  1. using System;

  2. using System.Net;

  3. namespace Client

  4. {

  5. class Program

  6.    {

  7. staticvoid Main(string[] args)

  8.        {

  9. //用一个WebClient就可以搞定了

  10.            var client = new WebClient();

  11. //以PUT方式访问Data/1/100,会映射到服务端的CreateData("1", "100")

  12.            client.UploadString("http://localhost:8080/wcf/Data/1/100", "PUT", string.Empty);

  13. //以GET方式访问Data/1,会映射到服务端的RetrieveData("1"),应该返回"100"

  14.            Console.WriteLine(client.DownloadString("http://localhost:8080/wcf/Data/1"));

  15. //以POST方式访问Data/1/200,会映射到服务端的UpdateData("1", "200")            

  16.            client.UploadString("http://localhost:8080/wcf/Data/1/200", "POST", string.Empty);

  17. //再GET一次,应该返回"200"

  18.            Console.WriteLine(client.DownloadString("http://localhost:8080/wcf/Data/1"));

  19. //以DELETE方式访问Data/1,会映射到服务端的DeleteData("1")

  20.            client.UploadString("http://localhost:8080/wcf/Data/1", "DELETE", string.Empty);

  21. //再GET一次,应该返回"NOT FOUND"

  22.            Console.WriteLine(client.DownloadString("http://localhost:8080/wcf/Data/1"));

  23.        }

  24.    }

  25. }


OK,运行一下客户端,返回如下,和预期一致:


需要补充一下,如果用IIS做HOST,比如DataService.svc.cs是实现类,一定要在DataService.svc中加上Factory,如下:

   
   
   
   
  1. <%@ ServiceHost Language="C#" Debug="true" Service="WebServer.DataService" CodeBehind="DataService.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

表明不是使用默认的ServiceHostFactory,而是适应WEB HTTP开发的WebServiceHostFactory。




你可能感兴趣的:(WCF)