.Net 的 RestFul Service

关于本文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(GETPOSTPUT, 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 项目:

QQ截图20131022141221

步骤二:

删掉自带的IService1.cs以及Service1.svc文件,同时建立如下两个文件:IRESTService.cs &RESTService.cs.

QQ截图20131022141505

步骤三:

在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
 
步骤六:
实如今RESTService类中实现IRESTService接口:
复制代码
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";
        }
    }
复制代码

 

步骤七:
为了让这个服务可以在ASP.NET兼容模式下运行,咱们须要利用AspNetCompatibilityRequirements特性来修饰RESTService类:
 [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";
        }
    }
}
复制代码

 

在上述的类中,类前面被打上了ServiceBehavior特性,主要是用来讲明这服务端只会存在这个类的一个实例.
 
步骤八:
若是要使用这个RESTFul Service应用,那么这个服务就必须得被寄宿.因此咱们必须作以下的更改才能让RESTService跑起来.
在Web.config文件中,移除掉<system.servicemodel>下面的全部代码,而且加入以下的新的代码:
<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))); 
 
步骤九:
运行这个应用:
咱们能够看到以下的页面:
QQ截图20131022144957
当运行 http://localhost:****/RestService/Help的时候,咱们能够看到以下页面:
QQ截图20131022145015
 
如何使用RESTFul Service呢?

客户端编程

这里我先贴出客户端代码:

  View Code

下面是利用WPF写的Client程序,当点击“建立用户”按钮的时候,显示的结果:

当点击“获取全部用户”的时候,会把全部用户的ID号给获取到:
当点击“获取某个用户”按钮时的结果(2号用户信息被获取):
当点击“更新某个用户”按钮时的结果(3号用户信息被更新):

当点击“删除某个用户”按钮时候的显示结果(4号用户被删除):

 

Client端的显示效果以下:

源码下载

 Click here to get source code

特别说明:本文转载自http://www.cnblogs.com/scy251147/p/3382436.html,可是文中的示例可以充分展现在客户端的CRUD的过程。
 
阿里巴巴早餐计划,我国每一年都有2000万人得胃病,很大一部分缘由是没有及时吃早餐。阿里计划每一年发放20亿早餐补贴来鼓励您及时吃早餐。 支付宝首页搜索547567984。 领取补贴,用于早餐消费等。天天都能领喔
相关文章
相关标签/搜索