概述
Representational State Transfer(REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。
因此REST是设计风格而不是标准,REST通常基于使用HTTP,URI,和JSON,XML以及HTML这些现有的广泛流行的协议和标准。
- 资源是由URI来指定,rest中的资源需要使用名词来命名。
- 对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
- 通过操作资源的表形来操作资源。
- 资源的表现形式则是XML,JSON或者两者都有。
REST的要求
- 显示的使用HTTP方法访问资源
- 连接协议具有无状态性
- 能够利用Cache机制增进性能
- 公开目录结构式的URL
- 在需要时可以传输Javascript (可选)
REST的优点
- 可以利用缓存Cache来提高响应速度
- 通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
- 浏览器即可作为客户端,简化软件需求
- 相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
- 不需要额外的资源发现机制
- 在软件技术演进中的长期的兼容性更好
在WCF中构建REST
一、按一下结构创建项目,其中WCF.REST.Services项目选用WCF REST Service Template 40(CS)模板
Contracts引用System.ServiceModel和System.ServiceModel.Web
Services引用Contracts
二、在Contracts项目中创建接口个传输类:传输类会在调用的客户端等地方使用,建议使用全小写,以免调用时产生疏忽。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
using System; namespace WCF.REST.Contracts { /// <summary> /// 该类用于传输 /// </summary> public class item { public int id { get ; set ; } public string name { get ; set ; } public decimal money { get ; set ; } public DateTime birthday { get ; set ; } public int number { get ; set ; } } } |
三、在Contracts项目中创建协议接口:在这里定义接口,方便维护,将接口和实现类进行分离。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
using System.Collections.Generic; using System.ServiceModel; using System.ServiceModel.Web; namespace WCF.REST.Contracts { /// <summary> /// 服务协议 /// </summary> [DataContractFormat] [ServiceContract] public interface IItem { [WebGet(UriTemplate = "" )] List<item> GetCollection(); [WebInvoke(UriTemplate = "" , Method = "POST" )] item Create(item instance); [WebGet(UriTemplate = "{id}" )] item Get( string id); [WebInvoke(UriTemplate = "{id}" , Method = "PUT" , BodyStyle = WebMessageBodyStyle.WrappedRequest)] item Update( string id, item instance); [WebInvoke(UriTemplate = "{id}" , Method = "DELETE" )] void Delete( string id); } } |
四、在Services中创建逻辑类,用于存储列表:真实项目时这个类可以单独放在业务逻辑层中。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
using System.Collections.Generic; using WCF.REST.Contracts; namespace WCF.REST.Services { /// <summary> /// 服务逻辑 /// </summary> public static class ItemsBL { public static List<item> list = new List<item>(); } } |
五、在Services中创建服务类:这是服务的具体实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
using System.Collections.Generic; using System.Linq; using System.ServiceModel.Activation; using WCF.REST.Contracts; namespace WCF.REST.Services { /// <summary> /// 服务实现 /// </summary> [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class Items : IItem { public List<item> GetCollection() { return ItemsBL.list; } public item Create(item instance) { lock (ItemsBL.list) { if (ItemsBL.list.Count > 0) instance.id = ItemsBL.list.Max(p => p.id) + 1; else instance.id = 1; } ItemsBL.list.Add(instance); return instance; } public item Get( string id) { return ItemsBL.list.FirstOrDefault(p => p.id == int .Parse(id)); } public item Update( string id, item instance) { int iid = int .Parse(id); item Result = null ; lock (ItemsBL.list) { if (ItemsBL.list.Count(p => p.id == iid) > 0) { ItemsBL.list.Remove(ItemsBL.list.FirstOrDefault(p => p.id == iid)); ItemsBL.list.Add(instance); Result = instance; } } return Result; } public void Delete( string id) { int iid = int .Parse(id); lock (ItemsBL.list) { if (ItemsBL.list.Count(p => p.id == iid) > 0) { ItemsBL.list.Remove(ItemsBL.list.FirstOrDefault(p => p.id == iid)); } } } } } |
六、修改Global文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
using System; using System.ServiceModel.Activation; using System.Web; using System.Web.Routing; namespace WCF.REST.Services { public class Global : HttpApplication { void Application_Start( object sender, EventArgs e) { RegisterRoutes(); } private void RegisterRoutes() { RouteTable.Routes.Add( new ServiceRoute( "Items" , new WebServiceHostFactory(), typeof (Items))); } } } |
七、运行服务在地址栏后添加 /items/help 后看到如下界面
ok至此服务部分完成。