http://www.oschina.net/translate/developing-restful-service-with-wcf-4-0-using-asp
实际上区别仅仅是客户端访问我们的服务的方式。通常的,一个WCF服务会使用SOAP,但是如果你构建了一个REST服务,客户端会使用一个不同的结构样式来访问你的服务(调用,如JSON一般的序列化,等等)。
REST使用一些常见的HTTP方法来插入、删除、更新、返回信息,这些方法如下:
- GET - 请求针对资源的特定表达式
- PUT - 根据提供的表达式创建或者更新一个资源
- DELETE - 删除指定的资源
- POST - 提交数据来让指定的资源处理
|
顶 翻译的不错哦! |
为什么使用REST,以及在哪里使用?
几天之前,我正在编写一个服务,它能够支持多种语言、平台或系统的访问。它可以被iPhone、Android、Windows Phone、.Net Web应用、Java或者PHP所使用。使用Web服务,使用统一的系统来将它展现给每个人,这对我来说有点复杂。之后,我决定使用REST,它更容易支持云。这是一个很好的例子,它表明了简单的“REST”的服务 :)。下面是一些重点,他们能够帮助你理解为什么使用“REST”的服务。
- 更少的开销(对于每次调用不需要包裹SOAP外壳)
- 更少的重复(HTTP已经提供了诸如DELETE、PUT、GET等等的方法,否则将表现在一个SOAP外壳当中)。
- 更标准化 - HTTP方法很容易理解并且操作一致。一些SOAP实现可能变得过分挑剔。
- 对于人类有更强的可读性和可测试性(很难仅仅用一个浏览器来测试SOAP)。
- 不需要使用XML(好吧,对于SOAP貌似也不需要使用,不过这很难成立,因为你已经开始解析外壳了)
- 库使得SOAP(有点)容易。但正如我提到的,你正在抽出大量的底层冗余。确实,在理论上,在避免装载功能相同的顶层这一项上,SOAP能够超过其他的转换;但是在现实中你可能做的几乎所有SOAP工作,都是通过HTTP的。
|
顶 翻译的不错哦! |
一步一步的指导
第一步:
创建名为WCFClasses的类库。在类库中创建类。
1. IGasPriceService.cs
WCF操作数据契约的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
[ServiceContract]
public
interface
IGasPriceService
{
[OperationContract]
[WebGet
(ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate =
"/GetGasPrice/For/ZipCode/{zipCode}"
)]
GasPriceData GetPriceByZipCode(
string
zipCode);
[OperationContract]
[WebGet
(RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate =
"/GetGasPrice/For/City/{city}"
)]
GasPriceData GetPriceByCity(
string
city);
}
|
WebGet属性
WebGet属性让我们能够定制在处理REST服务的过程中,如何处理HTTP的GET方法。如例子所示,我们在URL中呈现GET方法,并且我们期待返回一些POX(简单的旧式XML)结果。
- 请求格式:是发起请求的格式。两个选项是XML和JSON。如果你从浏览器请求,你的请求将会被重视。
- 响应格式:是返回的格式。两个选项是XML和JSON。在这里我们定制我们想要通过XML返回。
- 数据体样式:展现了我们希望怎样返回数据。我们希望没有XML还是全都“乱成一团”的XML?
|
顶 翻译的不错哦! |
实例 :
裸格式:
1
2
3
4
|
<
GasPriceData
>
<
GasStation
>HP</
GasStation
>
<
Price
>459</
Price
>
</
GasPriceData
>
|
有包装的格式:
1
2
3
4
5
6
|
<
GetPriceDataResponse
>
<
GetPriceDataResult
>
<
a:GasStation
>HP</
a:GasStation
>
<
a:Price
>459</
a:Price
>
</
GetPriceDataResult
>
</
GetPriceDataResponse
>
|
UriTemplate描述了我们将如何处理 Uri映射。这个例子中,我们声明了基地址(BaseAddress)之后的URL看起来是下面这样的: /GetGasPrice/For/ZipCode/{zipCode}
这就是服务合同,为我们REST服务实现了两个方法。一个通过城市名字得到天然气价格,另一个通过邮政编码获得。
|
顶 翻译的不错哦! |
Class 2: GasPriceService.cs
这个类是用来将数据返回给服务端。在现实场景中,它可能会连接到一些可以返回数据的数据存储区。
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
|
using
System.ServiceModel.Activation;
namespace
WCFClasses
{
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public
class
GasPriceService : IGasPriceService
{
#region Members
public
GasPriceData GetPriceByZipCode(
string
zipCode)
{
switch
(zipCode)
{
case
"00000"
:
return
new
GasPriceData { GasStation =
"None"
, Price = 0.00m };
case
"12345"
:
return
new
GasPriceData {GasStation =
"HP"
, Price = 420m};
case
"11111"
:
return
new
GasPriceData {GasStation =
"Indian Oil"
, Price = 531m};
default
:
return
new
GasPriceData {GasStation =
"DefaultGasPrice"
, Price = 400m};
}
}
public
GasPriceData GetPriceByCity(
string
city)
{
switch
(city.ToLower())
{
case
"hyderabad"
:
return
new
GasPriceData { GasStation =
"HP"
, Price = 459m };
case
"delhi"
:
return
new
GasPriceData { GasStation =
"Indian Oil"
, Price = 449m };
case
"chenni"
:
return
new
GasPriceData { GasStation =
"BG"
, Price = 499m };
default
:
return
new
GasPriceData { GasStation =
"DefaultGasPrice"
, Price = 409m };
}
}
#endregion
}
}
|
Class 3: GasPriceData.cs
举个用途例子,本端携带有天然气价格数据。当然作为一个实际的服务,这应该被实现为一个更健壮的对象模型。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
using
System.Runtime.Serialization;
namespace
WCFClasses
{
[DataContract]
public
class
GasPriceData
{
[DataMember]
public
string
GasStation {
get
;
set
; }
[DataMember]
public
decimal
Price {
get
;
set
; }
}
}
|
第2步
创建另一个Web应用程序项目命名为WebApplication1
托管代码如下:
- 添加 Global.asax
代码:Application_Start中:
1
2
3
4
5
6
7
8
9
10
11
|
protected
void
Application_Start(
object
sender, EventArgs e)
{
System.ServiceModel.Activation.WebServiceHostFactory WSHF =
new
System.ServiceModel.Activation.WebServiceHostFactory();
System.ServiceModel.Activation.ServiceRoute ss =
new
System.ServiceModel.Activation.ServiceRoute(
"wcfservice"
, WSHF,
typeof
(WCFClasses.GasPriceService));
System.Web.Routing.RouteTable.Routes.Add(ss);
}
|
- web.config
1
2
3
4
5
6
7
8
9
|
<
configuration
>
<
system.web
>
<
compilation
debug
=
"true"
targetFramework
=
"4.0"
/>
</
system.web
>
<
system.serviceModel
>
<
serviceHostingEnvironment
aspNetCompatibilityEnabled
=
"true"
multipleSiteBindingsEnabled
=
"true"
/>
</
system.serviceModel
>
</
configuration
>
|
|
顶 翻译的不错哦! |
服务准备测试现在
现在如果我用http://localhost:1486/wcfservice/GetGasPrice/For/ZipCode/11111 地址,我的浏览器得到的是下面的响应,它是XML格式的,正是我要达到的目标。
任何意见,建议,和批评都很欢迎。
|