WCF REST

今天我们就具体来看WCF REST 风格的使用以及传统WCF的调用。首先先来看WCF REST风格,关于Rest网上有很多解释,在此我就不说了。直接进入正题,先贴图。

我解释一下,这里有五个项目,一个是WCF Model,这里面定义了数据传输对象,以及服务对象。第一个要说的就是WCF Rest With No Config and SVC file。也就是一个Rest风格的WCF,既没有什么配置(Endpoint),也没有SVC 文件。我们看看代码,先看DTO\,代码如下

 
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Runtime.Serialization;  
  6. namespace WCF.Model  
  7. {  
  8.     [DataContract]  
  9.     public class Person  
  10.     {  
  11.         [DataMember]  
  12.         public string Name { getset; }  
  13.  
  14.         [DataMember]  
  15.         public int Age { getset; }  
  16.  
  17.         [DataMember]  
  18.         public string Description { getset; }  
  19.  
  20.         [DataMember]  
  21.         public string sex { getset; }  
  22.     }  
  23. }  

这个DTO不用多说,我们看看Service服务,

 
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.ServiceModel.Web;  
  6. using System.ServiceModel;  
  7.  
  8. namespace WCF.Model  
  9. {  
  10.     [ServiceContract]  
  11.     public interface IPersonService  
  12.     {  
  13.         [OperationContract]  
  14.         [WebGet(UriTemplate = "Get", ResponseFormat = WebMessageFormat.Json)]  
  15.         List<Person> GetPersonList();  
  16.  
  17.         [OperationContract]  
  18.         [WebInvoke(UriTemplate = "Delete/{name}",  
  19.             BodyStyle = WebMessageBodyStyle.Wrapped,  
  20.             ResponseFormat = WebMessageFormat.Json,  
  21.             Method = "POST")]  
  22.         Operation RemovePerson(string name);  
  23.     }  
  24. }  

这里需要解释的是UriTemplate,在这里我们把WCF Model这个类库引入到了WCFRestfulMvcDemo项目中。所以如果要访问GetPersonList这个方法的话,那么URI应该是http://localhost:1328/Person/Get,为什么是这个呢,在这里我要提到Globle中的一个配置,看看代码

 
 
  1. public static void RegisterRoutes(RouteCollection routes)  
  2.         {  
  3.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");  
  4.             routes.Add(new ServiceRoute("Person"new WebServiceHostFactory(), typeof(PersonService)));  
  5.             routes.MapRoute(  
  6.                 "Default"// Route name  
  7.                 "{controller}/{action}/{id}"// URL with parameters  
  8.                 new { controller = "Home", action = "Index", id = UrlParameter.Optional },  
  9.                 new { controller = "^(?!Person).*" }  
  10.             );  
  11.         } 

因为在这里我们配置了Rest Service的RoutePrefix为Person,所以完整路径就是上面所说的。routes.Add(new ServiceRoute("Person", new WebServiceHostFactory(), typeof(PersonService)));通过这段代码我们就可以将Rest Service像注册MVC路由一样对WCF服务进行注册。我们再看看实现

 
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.ServiceModel.Activation;  
  6. namespace WCF.Model  
  7. {  
  8.     [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
  9.     public class PersonService : IPersonService  
  10.     {  
  11.         List<Person> personList;  
  12.         public PersonService()  
  13.         {  
  14.             personList = new List<Person>()  
  15.             {  
  16.                 new Person(){ Name="lilei", Age=26, sex="男", Description="专注于C#,狂热的C#爱好者"},  
  17.                 new Person(){ Name="Snow",Age=29,sex="男",Description="专注于SQLServer,未来的DBA"},  
  18.                 new Person(){ Name="Strong",Age=30,sex="男",Description="专注于Silverlight"},  
  19.                 new Person(){ Name="Scry",Age=28,sex="男",Description="专注于测试"},  
  20.                 new Person(){ Name="lilei1", Age=26, sex="男", Description="专注于C#,狂热的C#爱好者"},  
  21.                 new Person(){ Name="Snow1",Age=29,sex="男",Description="专注于SQLServer,未来的DBA"},  
  22.                 new Person(){ Name="Strong1",Age=30,sex="男",Description="专注于Silverlight"},  
  23.                 new Person(){ Name="Scry1",Age=28,sex="男",Description="专注于测试"}  
  24.             };  
  25.         }  
  26.         public List<Person> GetPersonList()  
  27.         {  
  28.             return personList;  
  29.         }  
  30.  
  31.         public Operation RemovePerson(string name)  
  32.         {  
  33.             Person person = personList.SingleOrDefault(p => p.Name == "snow1");  
  34.             if (person != null)  
  35.             {  
  36.                 personList.Remove(person);  
  37.                 return new Operation() { Success = 1, Msg = "删除成功!" };  
  38.             }  
  39.             else 
  40.             {  
  41.                 return new Operation() { Success = 0, Msg = "删除失败!" };  
  42.             }  
  43.         }  
  44.     }  
  45. }  

在这里我们需要将AspNetCompatibilityRequirements设置为Allowed,同时在WebConfig中加入如下节点

 
 
  1. <system.serviceModel> 
  2.     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 
  3.     <standardEndpoints> 
  4.       <webHttpEndpoint> 
  5.         <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/> 
  6.       </webHttpEndpoint> 
  7.     </standardEndpoints> 
  8.   </system.serviceModel> 

OK,这样就可以在MVC控制器进行Rest 风格的WCF调用。我们看看后台控制器

 
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6. using System.Net;  
  7. using System.IO;  
  8.  
  9. namespace WCFRestfulMvcDemo.Controllers  
  10. {  
  11.     using Utility;  
  12.     using WCF.Model;  
  13.     public class HomeController : Controller  
  14.     {  
  15.         public ActionResult Index()  
  16.         {  
  17.             Uri uri = new Uri("http://localhost:1328/Person/Get");  
  18.             WebRequest webRequest = HttpWebRequest.Create(uri);  
  19.             WebResponse response = webRequest.GetResponse();  
  20.             Stream stream = response.GetResponseStream();  
  21.             List<Person> personList = SerializeHelper.JsonDeserialize<List<Person>>(stream);  
  22.  
  23.             //异步调用  
  24.             //WebClient webClient = new WebClient();  
  25.             //webClient.OpenReadAsync(uri);  
  26.             //webClient.OpenReadCompleted += delegate(object sender, OpenReadCompletedEventArgs e)  
  27.             //{  
  28.             //    stream = e.Result;  
  29.             //    personList = SerializeHelper.JsonDeserialize<List<Person>>(stream);  
  30.             //};  
  31.             return View("~/Views/Home/Person.cshtml", personList);  
  32.         }  
  33.     }  
  34. }  

为了不忽悠大家,防止大家怀疑没有EndPoint配置也没有SVC文件居然可以调用服务,我把运行效果图和前台代码给出来。

 
 
  1. @model IEnumerable<WCF.Model.Person> 
  2. <!DOCTYPE html> 
  3. <html> 
  4. <head> 
  5.     <meta name="viewport" content="width=device-width" /> 
  6.     <title>Person</title> 
  7.     <style type="text/css"> 
  8.         .mytable  
  9.         {  
  10.             background-color: transparent;  
  11.             position: relative;  
  12.             text-align: left;  
  13.             padding-left: 10px;  
  14.             color: #222222;  
  15.             font-family: Verdana,Arial,sans-serif;  
  16.             font-size: 12px;  
  17.             font-weight: 400;  
  18.             font-style: normal;  
  19.             width: 96%;  
  20.             border-collapse: collapse; /* 关键属性:合并表格内外边框(其实表格边框有2px,外面1px,里面还有1px哦) */  
  21.             border: solid #999; /* 设置边框属性;样式(solid=实线)、颜色(#999=灰) */  
  22.             border-width: 1px 0 0 1px; /* 设置边框状粗细:上 右 下 左 = 对应:1px 0 0 1px */  
  23.         }  
  24.         .mytable th  
  25.         {  
  26.             background: none repeat scroll 0 0 #EEEEEE;  
  27.             font-family: "Lucida Sans Unicode" , "Lucida Grande" ,Sans-Serif;  
  28.             height: 23px;  
  29.             border: solid #999;  
  30.             border-width: 0 1px 1px 0;  
  31.             padding: 2px;  
  32.         }  
  33.         .mytable tr td  
  34.         {  
  35.             height: 23px;  
  36.             border: solid #999;  
  37.             border-width: 0 1px 1px 0;  
  38.             padding: 2px;  
  39.             background-color: #FFF;  
  40.         }  
  41.         .mytable tr:hover td  
  42.         {  
  43.             border: 1px solid #999999;  
  44.             background: #EEEEEE;  
  45.             font-weight: normal;  
  46.             color: #212121;  
  47.         }  
  48.     </style> 
  49. </head> 
  50. <body> 
  51.     <div align="center"> 
  52.         <table class="mytable"> 
  53.             <tr> 
  54.                 <th> 
  55.                     <center> 
  56.                         姓名</center> 
  57.                 </th> 
  58.                 <th> 
  59.                     <center> 
  60.                         性别</center> 
  61.                 </th> 
  62.                 <th> 
  63.                     <center> 
  64.                         年龄</center> 
  65.                 </th> 
  66.                 <th> 
  67.                     <center> 
  68.                         描述</center> 
  69.                 </th> 
  70.             </tr> 
  71.             @foreach (WCF.Model.Person person in Model)  
  72.             {  
  73.                 <tr> 
  74.                     <td> 
  75.                         @person.Name  
  76.                     </td> 
  77.                     <td> 
  78.                         @person.sex  
  79.                     </td> 
  80.                     <td> 
  81.                         @person.Age  
  82.                     </td> 
  83.                     <td> 
  84.                         @person.Description  
  85.                     </td> 
  86.                 </tr>   
  87.             }  
  88.         </table> 
  89.     </div> 
  90. </body> 
  91. </html> 

运行效果图

如果您还不信,请看http://geekswithblogs.net/michelotti/archive/2010/08/21/restful-wcf-services-with-no-svc-file-and-no-config.aspx,一个国外的MVP写的。

接下来我们看看传统的WCF,也就是有SVC也有Config。为了复用,我们在项目WCFService.Host上引用WCFModel程序集并在该项目下新建一个PersonService.svc,注意,只建一个svc文件,在该文件上点击右键,选择用XML格式打开,我们修改其内部代码如下

 
 
  1. <%@ ServiceHost Language="C#" Debug="true" Service="WCF.Model.PersonService" CodeBehind="WCF.Model.PersonService" %> 

我们将其Service指定到引用的WCFModel程序集的PersonService类上。这个时候我们首先以最传统的方式也就是借助VS2010来引用服务。如下所示

因为WCFService.Host程序集的端口号是1010,所以引用的服务地址就是上面看到的。引用完以后我们在WCFRestfulWebFromsDemo项目中测试。因为自动生成了代理,我们直接看代码和运行效果

 
 
  1. namespace WCFRestfulWebFromsDemo  
  2. {  
  3.     using PersonServiceReference;  
  4.     public partial class PersonInfo : System.Web.UI.Page  
  5.     {  
  6.         protected void Page_Load(object sender, EventArgs e)  
  7.         {  
  8.             if (!IsPostBack)  
  9.             {  
  10.                 PersonServiceClient serviceClient = new PersonServiceClient();  
  11.                 List<Person> personList = serviceClient.GetPersonList();  
  12.                 Gridview1.DataSource = personList;  
  13.                 Gridview1.DataBind();  
  14.             }  
  15.         }  
  16.     }  

还有一种比较酷的调用方式,我们来看看。

首先我们在IPersonService中加入一个操作[OperationContract] string GetPersons();然后实现方法返回一个Json格式对象。

 
 
  1. public string GetPersons()  
  2.         {  
  3.             return SerializeHelper.JsonSerialize<List<Person>>(personList);  
  4.         } 

这个时候我们在WCFRestfulWebFromsDemo页面中调用,代码如下

 
 
  1. namespace WCFRestfulWebFromsDemo  
  2. {  
  3.     using Utility;  
  4.     using WCFRestfulWebFromsDemo.Model;  
  5.     public partial class PersonInfo1 : System.Web.UI.Page  
  6.     {  
  7.         protected void Page_Load(object sender, EventArgs e)  
  8.         {  
  9.             if (!IsPostBack)  
  10.             {  
  11.                 ContractDescription con = ContractDescription.GetContract(typeof(IPersonService));  
  12.                 ServiceEndpoint serviceEndPoint = new ServiceEndpoint(con, new BasicHttpBinding(), new EndpointAddress("http://localhost:1010/PersonService.svc"));  
  13.                 using (ChannelFactory<IPersonService> ChannelFactory = new ChannelFactory<IPersonService>(serviceEndPoint))  
  14.                 {  
  15.                     IPersonService personService = ChannelFactory.CreateChannel();  
  16.                     string personJson = personService.GetPersons();  
  17.                     List<Person> personList = SerializeHelper.JsonDeserialize<List<Person>>(personJson);  
  18.                     this.Gridview1.DataSource = personList;  
  19.                     this.Gridview1.DataBind();  
  20.                 }  
  21.             }  
  22.         }  
  23.     }  

其中我要说明的是在这里这种调用方式也不需要读取Config中的EndPoint配置,而是通过代码来配置。在这里这种动态调用方式需要在项目中建立和WCF服务相同的服务接口以及DTO,如下

这样调用方才能知道这个服务提供哪些操作。OK,我们看看运行效果



本文转自 BruceAndLee 51CTO博客,原文链接:http://blog.51cto.com/leelei/876710,如需转载请自行联系原作者


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值