在现代软件开发中,RESTful服务因其简洁性和易于理解的特点而受到广泛欢迎。本文将介绍如何使用.NET 3.5中的Windows Communication Foundation (WCF)技术来创建RESTful服务。将探索如何利用WCF的System.ServiceModel.Web
命名空间来实现REST风格的服务。
REST(Representational State Transfer)是一种软件架构风格,用于构建分布式超媒体系统,如万维网。REST的核心是资源的概念,资源通过URI进行标识,并通过HTTP协议进行访问。RESTful服务通常使用HTTP方法(如GET、POST、PUT、DELETE)来执行CRUD(创建、读取、更新、删除)操作。
在WCF中,要创建RESTful服务,需要使用两个关键属性:WebGetAttribute
和WebInvokeAttribute
。这两个属性允许将服务操作与HTTP动词和URI模板关联起来。
WebGetAttribute
通常用于GET请求,用于从服务中检索信息。而WebInvokeAttribute
则用于表示一个调用操作,可以与HTTP POST、PUT或DELETE等动词关联。这两个属性都是被动操作行为,它们通过添加元数据到操作描述中来工作。除非服务的行为集合中添加了WebHttpBehavior
,否则这些属性不会生效。
下面是一个使用WebGetAttribute
的简单示例。这个示例展示了如何通过URL暴露资源。
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public interface ISomeService
{
[OperationContract]
[WebGet(UriTemplate = "/")]
Message GetRoot();
[OperationContract]
[WebGet(UriTemplate = "/{userName}/")]
Message GetFavouriteBarsForUser(String userName);
}
在这个例子中,定义了一个服务接口ISomeService
,它有两个操作:GetRoot
和GetFavouriteBarsForUser
。这两个操作都使用了WebGetAttribute
,这意味着它们可以通过HTTP GET请求来访问。
UriTemplate
属性用于定义资源的URI模式。例如,"/"
表示根资源,而"/{userName}/"
表示特定用户的资源,其中{userName}
是一个参数,可以从URL中提取。
接下来,需要实现这个服务接口。下面是一个简单的服务实现示例。
[ServiceBehavior(IncludeExceptionDetailInFaults = false, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
public class SomeService : ISomeService
{
public Message GetRoot()
{
Message message = GetRootMessage();
return message;
}
public Message GetFavouriteBarsForUser(String userName)
{
Message message = GetFavouriteBarsForUserMessage(userName);
return message;
}
private Message GetFavouriteBarsForUserMessage(String userName)
{
var stream = new MemoryStream();
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream);
writer.WriteStartDocument();
writer.WriteStartElement("Root");
writer.WriteStartElement("Bar");
writer.WriteElementString("user", userName);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
stream.Position = 0;
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, XmlDictionaryReaderQuotas.Max);
return Message.CreateMessage(MessageVersion.None, "", reader);
}
private Message GetRootMessage()
{
var stream = new MemoryStream();
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream);
writer.WriteStartDocument();
writer.WriteStartElement("Root");
writer.WriteStartElement("Hello");
writer.WriteElementString("Name", "sacha");
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
stream.Position = 0;
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, XmlDictionaryReaderQuotas.Max);
return Message.CreateMessage(MessageVersion.None, "", reader);
}
}
在这个实现中,定义了两个私有方法GetRootMessage
和GetFavouriteBarsForUserMessage
,它们分别用于创建根资源和用户资源的消息。这些消息是XML格式的,浏览器可以解析并显示。
要测试这个服务,需要一个简单的主机程序。以下是一个简单的控制台应用程序,它可以用来测试RESTful WCF服务。
运行这个主机程序后,可以通过浏览器访问以下URL来测试服务:
通过这些URL,可以看到服务如何通过RESTful方式暴露资源。这些资源可以通过浏览器直接访问,浏览器会解析返回的XML消息。