使用 ASP.NET 和 WCF 4.0 开发 RESTful 服务

http://www.oschina.net/translate/developing-restful-service-with-wcf-4-0-using-asp

实际上区别仅仅是客户端访问我们的服务的方式。通常的,一个WCF服务会使用SOAP,但是如果你构建了一个REST服务,客户端会使用一个不同的结构样式来访问你的服务(调用,如JSON一般的序列化,等等)。

REST使用一些常见的HTTP方法来插入、删除、更新、返回信息,这些方法如下:

  1. GET - 请求针对资源的特定表达式
  2. PUT - 根据提供的表达式创建或者更新一个资源
  3. DELETE - 删除指定的资源
  4. POST - 提交数据来让指定的资源处理
尚御博豪
尚御博豪
翻译于 2年前

0人顶

 翻译的不错哦!

为什么使用REST,以及在哪里使用?

几天之前,我正在编写一个服务,它能够支持多种语言、平台或系统的访问。它可以被iPhone、Android、Windows Phone、.Net Web应用、Java或者PHP所使用。使用Web服务,使用统一的系统来将它展现给每个人,这对我来说有点复杂。之后,我决定使用REST,它更容易支持云。这是一个很好的例子,它表明了简单的“REST”的服务 :)。下面是一些重点,他们能够帮助你理解为什么使用“REST”的服务。

  1. 更少的开销(对于每次调用不需要包裹SOAP外壳)
  2. 更少的重复(HTTP已经提供了诸如DELETE、PUT、GET等等的方法,否则将表现在一个SOAP外壳当中)。
  3. 更标准化 - HTTP方法很容易理解并且操作一致。一些SOAP实现可能变得过分挑剔。
  4. 对于人类有更强的可读性和可测试性(很难仅仅用一个浏览器来测试SOAP)。
  5. 不需要使用XML(好吧,对于SOAP貌似也不需要使用,不过这很难成立,因为你已经开始解析外壳了)
  6. 库使得SOAP(有点)容易。但正如我提到的,你正在抽出大量的底层冗余。确实,在理论上,在避免装载功能相同的顶层这一项上,SOAP能够超过其他的转换;但是在现实中你可能做的几乎所有SOAP工作,都是通过HTTP的。
尚御博豪
尚御博豪
翻译于 2年前

0人顶

 翻译的不错哦!

一步一步的指导

第一步:

创建名为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?
尚御博豪
尚御博豪
翻译于 2年前

0人顶

 翻译的不错哦!

实例 :

裸格式:

?
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服务实现了两个方法。一个通过城市名字得到天然气价格,另一个通过邮政编码获得。

super0555
super0555
翻译于 2年前

0人顶

 翻译的不错哦!

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

托管代码如下:

  1. 添加 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);
     
    }
  2. 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 >


super0555
super0555
翻译于 2年前

0人顶

 翻译的不错哦!

服务准备测试现在

现在如果我用http://localhost:1486/wcfservice/GetGasPrice/For/ZipCode/11111 地址,我的浏览器得到的是下面的响应,它是XML格式的,正是我要达到的目标。

任何意见,建议,和批评都很欢迎。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值