概述
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至此服务部分完成。