RESTful WCF - 第一部分





5.00/5 (2投票s)
RESTful WCF
最近,我有点疏忽了我的编码职责,去外面喝酒了。我现在有点厌倦了,所以回到了代码,这是一个好地方。
现在我正在创作另一篇文章,虽然我不能透露我在做什么,因为有一个比赛,我想参加,但我想在过程中分享一些关于它的部分信息。
我可以说我正在使用 .NET 3.5 附带的一些新的 WCF 功能,即 System.ServiceModel.Web 命名空间
,它允许我们创建 RESTful WCF 服务。
对于那些不知道 REST 是什么的人,维基百科是这样说的。
"Representational state transfer (REST) 是一种软件架构风格,适用于像万维网这样的分布式超媒体系统。因此,它严格来说并不是一种构建“Web 服务”的方法。术语“representational state transfer”和“REST”于 2000 年在 Roy Fielding 的博士论文中首次提出,Roy Fielding 是超文本传输协议 (HTTP) 规范的主要作者之一。
REST 严格来说是指一组网络架构原则,这些原则概述了资源的定义和寻址方式。该术语通常以更宽泛的意义使用,用于描述任何通过 HTTP 传输领域特定数据的简单接口,而无需额外的消息层,如 SOAP 或通过 HTTP cookie 进行会话跟踪。这两种含义可能会发生冲突和重叠。有可能设计一个符合 Fielding 的 REST 架构风格的软件系统,而无需使用 HTTP,也无需与万维网交互。[2] 也有可能设计不符合 REST 原则的简单 XML+HTTP 接口,而是遵循远程过程调用模型。因此,“REST”术语用法之间的差异会在技术讨论中引起一些混淆。
遵循 Fielding 的 REST 原则的系统通常被称为“RESTful”。
http://en.wikipedia.org/wiki/Representational_State_Transfer
对于 WCF 开发者来说,这基本上意味着您将公开可以通过 URL 访问的资源,这意味着客户端使用您的服务只需要一个浏览器。
文章的发布时间表可能会是这样的
- 新的 RESTful WCF 属性 (本文)
- 序列化选项
- 托管
- 使用 RESTful WCF 进行 CRUD 操作
好的,现在让我们开始看一些代码。
这篇博文将只介绍支持 RESTful WCF 的新属性。
事实上,在我看来,只有两个属性是使用 WCF 进行 RESTful 操作的关键。这些属性是
WebGetAttribute
"WebGetAttribute 属性除了应用于服务操作的 OperationContractAttribute 外,还将其与 UriTemplate 以及 HTTP GET 动词相关联。与 HTTP GET 动词的关联意味着该操作用于从服务检索信息。WebGetAttribute 属性是一种被动操作行为( IOperationBehavior 方法不执行任何操作),它向操作描述添加元数据。除非将查找操作描述中此元数据的行为(例如 WebHttpBehavior)添加到服务的行为集合中,否则将 WebGetAttribute 应用于服务操作无效。"
MSDN
WebInvokeAttribute
"WebInvokeAttribute 属性除了应用于服务操作的 OperationContractAttribute 外,还将其与 UriTemplate 以及代表调用的底层传输动词(例如 HTTP POST、PUT 或 DELETE)相关联。WebInvokeAttribute 属性是一种被动操作行为( IOperationBehavior 方法不执行任何操作),它向操作描述添加元数据。除非将查找操作描述中此元数据的行为(例如 WebHttpBehavior)添加到服务的行为集合中,否则将 WebInvokeAttribute 应用于服务操作无效。WebInvokeAttribute 确定服务操作响应的是哪个 HTTP 方法。默认情况下,所有应用了 WebInvokeAttribute 的方法都响应 POST 请求。 Method 属性允许您指定不同的 HTTP 方法。如果要让服务操作响应 GET,请改用 WebGetAttribute。"
MSDN
现在让我们来看一些使用这些属性之一的 WCF 代码。在本文中,我将只讨论 WebGetAttribute
的用法,因为我现在不想讨论 RESTful WCF 可以执行的所有 CRUD 操作。
因此,为了通过 URL 公开资源,我们可以使用 WebGetAttribute
来修饰我们的 WCF 服务操作。这是一个例子
1: [ServiceContract(SessionMode =
2: SessionMode.NotAllowed)]
3: public interface ISomeService
4: {
5:
6: [OperationContract]
7: [WebGet(UriTemplate = "/")]
8: Message GetRoot();
9:
10: [OperationContract]
11: [WebGet(UriTemplate = "/{userName}/")]
12: Message GetFavouriteBarsForUser(
13: String userName);
14: }
请注意,我使用 WebGetAttribute
来修饰 WCF OperationContract
方法。还要注意有一个 UriTemplate
属性,它被设置为根终止符“/
”或具有 URL 的更多部分,其中 URL 的额外部分被视为方法参数,这允许公开更具体的资源。
本质上,这就是公开资源服务的全部内容。现在我们需要测试它。为了做到这一点,我们需要实现这个示例服务,所以让我们看看我匆忙完成的一个小型演示应用程序。
1: [ServiceBehavior(IncludeExceptionDetailInFaults = false,
2: InstanceContextMode = InstanceContextMode.Single,
3: ConcurrencyMode = ConcurrencyMode.Single)]
4: public class SomeService : ISomeService
5: {
6:
7: #region ISomeService Members
8:
9: public Message GetRoot()
10: {
11:
12: Message message = GetRootMessage();
13: return message;
14: }
15:
16:
17:
18: public Message
19: GetFavouriteBarsForUser(string userName)
20: {
21: Message message =
22: GetFavouriteBarsForUserMessage(userName);
23: return message;
24: }
25:
26: #endregion
27:
28: #region Private Methods
29:
30: /// <summary>
31: /// Create bars for User message
32: /// </summary>
33: private Message
34: GetFavouriteBarsForUserMessage(String userName)
35: {
36: var stream = new MemoryStream();
37: XmlDictionaryWriter writer =
38: XmlDictionaryWriter.CreateTextWriter(stream);
39: writer.WriteStartDocument();
40: writer.WriteStartElement("Root");
41: writer.WriteStartElement("Bar");
42: writer.WriteElementString("user", userName);
43: writer.WriteEndElement();
44: writer.WriteEndElement();
45: writer.WriteEndDocument();
46: writer.Flush();
47: stream.Position = 0;
48:
49: XmlDictionaryReader reader =
50: XmlDictionaryReader.CreateTextReader(stream,
51: XmlDictionaryReaderQuotas.Max);
52: return Message.CreateMessage(
53: MessageVersion.None, "", reader);
54: }
55:
56:
57: /// <summary>
58: /// Create root message
59: /// </summary>
60: private Message GetRootMessage()
61: {
62: var stream = new MemoryStream();
63: XmlDictionaryWriter writer =
64: XmlDictionaryWriter.CreateTextWriter(stream);
65: writer.WriteStartDocument();
66: writer.WriteStartElement("Root");
67: writer.WriteStartElement("Hello");
68: writer.WriteElementString("Name", "sacha");
69: writer.WriteEndElement();
70: writer.WriteEndElement();
71: writer.WriteEndDocument();
72: writer.Flush();
73: stream.Position = 0;
74:
75: XmlDictionaryReader reader =
76: XmlDictionaryReader.CreateTextReader(
77: stream, XmlDictionaryReaderQuotas.Max);
78: return Message.CreateMessage(
79: MessageVersion.None, "", reader);
80: }
81: #endregion
82: }
所以您可以看到,对于每个带有 WebGetAttribute
修饰的 WCF OperationContract
方法,我们将返回一个 Message
,它实际上只是一些 XML,浏览器知道如何显示它。如果您不知道 Message 类型是什么,请不要担心,我们将在后续的文章中进行介绍。
目前,重要的是要注意该服务正在通过 URL 使用 REST 公开资源。
附带的演示代码包含一个简单的宿主,运行后您就可以测试各种 REST 调用了。
您需要这样做
- 运行简单的宿主 (SomeServiceTestConsole.exe)
- 打开浏览器并尝试以下 URL
您应该看到这样的结果
https://:8085/SomeService/sacha
我希望您可以看到,通过使用这些新的 RESTful 属性,我们可以通过 URL 公开资源,而这些资源只需使用浏览器即可访问。当然,要解析 XML,还有很多选项。
这里有一个小型演示应用程序,它有一个非常简单的 RESTful 服务和一个非常简单的控制台宿主。