现在我们可以用 WCF 4 轻易构建一个REST Service,如何测试呢?
首先让我们来看类图:

ClassDiagram

代码是这样的:

   1:      [ServiceContract]
   2:      public interface IDataService
   3:      {
   4:            [OperationContract]
   5:            [WebGet(UriTemplate = "/Get?id={id}")]
   6:            Employee Get(int id);
   7:   
   8:            [OperationContract]
   9:            [WebInvoke(UriTemplate = "/Update?id={id}", Method = "PUT")]
  10:            bool Update(int id);
  11:   
  12:            [OperationContract]
  13:            [WebInvoke(UriTemplate = "/Del?id={id}", Method = "DELETE")]
  14:            bool Delete(int id);
  15:   
  16:            [OperationContract]
  17:            [WebInvoke(UriTemplate = "Create", Method = "POST")]
  18:            bool Create(Employee employee);
  19:      }

Entity class:

   1:      [DataContract]
   2:      public partial class Employee 
   3:      {
   4:          public Employee()
   5:          {}
   6:   
   7:          [DataMember]
   8:          public int EmployeeID { get; set; }
   9:          [DataMember]
  10:          public string NationalIDNumber { get; set; }
  11:          [DataMember]
  12:          public int ContactID { get; set; }
  13:          [DataMember]
  14:          public string LoginID { get; set; }
  15:          [DataMember]
  16:          public Nullable<int> ManagerID { get; set; }
  17:          [DataMember]
  18:          public string Title { get; set; }
  19:          [DataMember]
  20:          public System.DateTime BirthDate { get; set; }
  21:          [DataMember]
  22:          public string MaritalStatus { get; set; }
  23:          [DataMember]
  24:          public string Gender { get; set; }
  25:          [DataMember]
  26:          public System.DateTime HireDate { get; set; }
  27:          [DataMember]
  28:          public bool SalariedFlag { get; set; }
  29:          [DataMember]
  30:          public short VacationHours { get; set; }
  31:          [DataMember]
  32:          public short SickLeaveHours { get; set; }
  33:          [DataMember]
  34:          public bool CurrentFlag { get; set; }
  35:          [DataMember]
  36:          public System.Guid rowguid { get; set; }
  37:          [DataMember]
  38:          public System.DateTime ModifiedDate { get; set; }
  39:      }

实现的service,为了演示这里只是简单实现。

   1:      /// <summary>
   2:      /// CRUD Service  http://www.cnblogs.com/wintersun
   3:      /// </summary>
   4:      public class CRUDService : IDataService
   5:      {
   6:          public Employee Get(int id)
   7:          {
   8:              return new Employee() { EmployeeID = 11, Title = "Engineer" };
   9:          }
  10:   
  11:          public bool Update(int id)
  12:          {
  13:              //TODO
  14:              return true;
  15:          }
  16:   
  17:          public bool Delete(int id)
  18:          {
  19:              //TODO
  20:              return true;
  21:          }
  22:   
  23:          public bool Create(Employee employee)
  24:          {
  25:              //TODO
  26:              return true;
  27:          }
  28:      }

Config文件是这样的:

   1:    <system.serviceModel>
   2:      <services>
   3:        <service name="webdemo.CRUDService" behaviorConfiguration="ServiceBehaviour">
   4:          <endpoint address=""  binding="webHttpBinding" contract="webdemo.IDataService" behaviorConfiguration="web">
   5:          </endpoint>
   6:        </service>
   7:      </services>
   8:      <behaviors>
   9:        <endpointBehaviors>
  10:          <behavior name="web">
  11:            <webHttp />
  12:          </behavior>
  13:        </endpointBehaviors>
  14:        <serviceBehaviors>
  15:          <behavior name="ServiceBehaviour">
  16:            <serviceMetadata httpGetEnabled="true" />
  17:            <serviceDebug includeExceptionDetailInFaults="false" />
  18:          </behavior>
  19:          <behavior>
  20:            <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
  21:            <serviceMetadata httpGetEnabled="true"/>
  22:            <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
  23:            <serviceDebug includeExceptionDetailInFaults="false"/>
  24:          </behavior>
  25:        </serviceBehaviors>
  26:      </behaviors>
  27:      <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  28:    </system.serviceModel>

注意,我们使用是webHttpBinding,在DEBUG时可以把includeExceptionDetailInFaults设置为true. 我们通用会使用Svcutil.exe生成proxy类,但对webHttpBinding是不会生成Output.config的。

当我们编译,Host这个Service,你从浏览器中打开类似这样的URL:

http://localhost:50422/CRUDService.svc

调用Get的时序图,其它方法类似了。

sequcesp

对于Http Get 操作我们可以直接在浏览器测试,当我们访问

http://localhost:50422/CRUDService.svc/Get?Id=1

Http_get_Browse

我们用Fiddler来测试,它有一个功能是Request Builder,下面来测试Get方法, Request RAW:

GET http://localhost:50422/CRUDService.svc/Get?id=1 HTTP/1.1
User-Agent: Fiddler
Host: localhost:50422

然后Response RAW是这样的:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 28 Jun 2011 06:18:05 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 651
Cache-Control: private
Content-Type: application/xml; charset=utf-8
Connection: Close

<Employee xmlns="http://schemas.datacontract.org/2004/07/webdemo" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><BirthDate>0001-01-01T00:00:00</BirthDate><ContactID>0</ContactID><CurrentFlag>false</CurrentFlag><EmployeeID>11</EmployeeID><Gender i:nil="true"/><HireDate>0001-01-01T00:00:00</HireDate><LoginID i:nil="true"/><ManagerID i:nil="true"/><MaritalStatus i:nil="true"/><ModifiedDate>0001-01-01T00:00:00</ModifiedDate><NationalIDNumber i:nil="true"/><SalariedFlag>false</SalariedFlag><SickLeaveHours>0</SickLeaveHours><Title>Engineer</Title><VacationHours>0</VacationHours><rowguid>00000000-0000-0000-0000-000000000000</rowguid></Employee>

Request PUT :

PUT http://localhost:50422/CRUDService.svc/Update?id=1 HTTP/1.1
User-Agent: Fiddler
Host: localhost:50422

Response RAW:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 28 Jun 2011 06:20:15 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 83
Cache-Control: private
Content-Type: application/xml; charset=utf-8
Connection: Close

<boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean>

HTTP-PUT操作对我们的Update方法。接着是HTTP-DELETE, Request header RAW :

DELETE http://localhost:50422/CRUDService.svc/Del?id=1 HTTP/1.1
User-Agent: Fiddler
Host: localhost:50422

Response RAW:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 28 Jun 2011 06:21:01 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 83
Cache-Control: private
Content-Type: application/xml; charset=utf-8
Connection: Close

<boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean>

最后测试的是HTTP-POST方法,这个大家比较熟悉. Request RAW header:

POST http://localhost:50422/CRUDService.svc/Create HTTP/1.1
User-Agent: Fiddler
Content-Type: application/xml; charset=utf-8
Host: localhost:50422
Content-Length: 652

与前面不同我们还需要POST一个BODY,在Server端WCF会帮我们把XML反序列化成Object. 

<Employee xmlns="http://schemas.datacontract.org/2004/07/webdemo" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><BirthDate>0001-01-01T00:00:00</BirthDate><ContactID>0</ContactID><CurrentFlag>false</CurrentFlag><EmployeeID>11</EmployeeID><Gender i:nil="true"/><HireDate>0001-01-01T00:00:00</HireDate><LoginID i:nil="true"/><ManagerID i:nil="true"/><MaritalStatus i:nil="true"/><ModifiedDate>0001-01-01T00:00:00</ModifiedDate><NationalIDNumber i:nil="true"/><SalariedFlag>false</SalariedFlag><SickLeaveHours>0</SickLeaveHours><Title>asdfasd</Title><VacationHours>0</VacationHours><rowguid>00000000-0000-0000-0000-000000000000</rowguid></Employee>

这里是基于XML的格式数据。看截图:

fiddle_sp2

POST方法Response RAW:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 28 Jun 2011 06:22:29 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 83
Cache-Control: private
Content-Type: application/xml; charset=utf-8
Connection: Close

<boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean>

前面几次操作如下图,您可能注意到这个方法都返回是bool值,对应上面RAW

fiddle_sp3

我们看到返回都是200就OK了。强烈建议你使用VS来DEBUG整个流程。这个REST Service提供了CRUD刚好对应了Http-GET,Http-POST,Http-DELETE,Http-PUT的操作。实际使用过程,可能还需要注意安全方面的因素。

下一次将为您介绍另一种方法测试基于Web WCF Service。

您可能感兴趣的文章:

C#实现一个简单的REST service

希望这篇POST对您开发有帮助。


作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog

posted on 2011-06-28 15:31  PetterLiu  阅读(2718)  评论(0编辑  收藏  举报