高级 Web 编程
本示例演示 Windows Communication Foundation (WCF) Web 编程模型的一些更高级的功能。该示例介绍了以下概念:
- URI 模板调度 – 允许将服务操作绑定到与指定模式匹配的外部 URI。
- HTTP 方法 – 可以使用任意 HTTP 方法(包括 GET、PUT、POST 和 DELETE)调用服务操作。
- HTTP 标头 – 服务使用 WebOperationContext 可以操作 HTTP 标头的内容。
提示
此示例需要安装 .NET Framework 3.5 版才能生成和运行。若要打开项目和解决方案文件,需要使用 Visual Studio 2008。
该示例实现存储在内存中的基本客户数据集合。本示例支持使用 URI 和 HTTP 方法在外部公开的基本的 Create
、Read
、Update
和 Delete
操作。
服务协定和实现
在本示例中,服务实现在基本 URI 地址 (https://localhost:8000/Customers) 上侦听的单个终结点。服务通过以下方式处理对该前缀下的 URI 的请求:
- 对 https://localhost:8000/Customers 的 GET 请求路由到
GetCustomers()
。 - 系统中的每个客户都具有一个唯一标识符,在 URI 中带有此标识符。对这些 URI(例如 https://localhost:8000/Customers/1)的 GET 请求映射到
GetCustomer()
。 - 通过向客户的 URI 发出 HTTP PUT 请求可以更新各个客户。
- 通过向客户的 URI 发出 HTTP DELETE 可以从系统中移除该客户。
- 通过向基本 URI 发出 HTTP POST 可以向系统添加新数据。
[ServiceContract]
public interface ICustomerCollection
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "")]
Customer AddCustomer(Customer customer);
[OperationContract]
[WebInvoke(Method = "DELETE", UriTemplate = "{id}")]
void DeleteCustomer(string id);
[OperationContract]
[WebGet(UriTemplate = "{id}")]
Customer GetCustomer(string id);
[OperationContract]
[WebGet(UriTemplate = "")]
List<Customer> GetCustomers();
[OperationContract]
[WebInvoke(Method = "PUT", UriTemplate = "{id}")]
Customer UpdateCustomer(string id, Customer newCustomer);
}
服务协定由 Service
类实现,该类使用 WCF 单一实例进行实例化。所有接收的请求都路由到服务器上的同一个对象实例,这允许在请求之间共享客户的哈希表。
[ServiceBehavior( InstanceContextMode = InstanceContextMode.Single )]
public class Service : ICustomerCollection
{
Hashtable customers = new Hashtable();
...
}
通过向服务的基本 URI(例如 https://localhost:8000/Customers)发出 HTTP GET 请求可以调用 GetCustomers()
操作。用Data Contract Serializer序列化 Customer
类型。
public List<Customer> GetCustomers()
{
List<Customer> list = new List<Customer>();
foreach (Customer c in this.customers.Values)
{
list.Add(c);
}
return list;
}
通过向客户的唯一 URI 发出 GET 请求可以检索各个客户。例如,在 https://localhost:8000/Customers/1 上可以检索具有 ID 1 的客户。同样,可以在 http:/localhost:8000/Customers/2 上访问客户 2。这两个 URI 都被调度到服务器上的 GetCustomer(string id)
方法。此映射由应用于 GetCustomer()
操作协定的 [WebGet( UriTemplate="{id}")]
属性所创建。UriTemplate 是一种模式,用于描述 GetCustomer()
操作处理的一组 URI。在本示例中,模式描述所有在终结点的基址后面只有一个段的 URI。该段的内容与 {id}
模板变量匹配并被 WCF 调度程序传入到方法参数 id
。
//[WebGet( UriTemplate=”{id}” )]
public Customer GetCustomer(string id)
{
Customer c = this.customers[id] as Customer;
if (c == null)
{
WebOperationContext.Current.OutgoingResponse.SetStatusAsNotFound();
return null;
}
return c;
}
GetCustomer()
的实现查找客户 ID(在 URI 中提供)并返回关联的客户。如果找不到客户,则操作通过使用 WebOperationContext 方法设置响应状态代码来返回 HTTP 404 响应。
请注意,与 GetCustomer()
方法一样,UpdateCustomer()
和 DeleteCustomer()
方法也与同一个 URI 模板关联。在每个操作与不同的 HTTP 方法关联时,WCF Web 编程模型允许将多个操作绑定到同一个 URI 模板。在本例中,UpdateCustomer()
方法绑定到 HTTP PUT 方法,而 DeleteCustomer()
操作绑定到 HTTP DELETE 方法。
[OperationContract]
[WebInvoke( Method="PUT", UriTemplate="{id}")]
Customer UpdateCustomer(string id, Customer newCustomer);
[OperationContract]
[WebInvoke( Method="DELETE", UriTemplate="{id}" )]
void DeleteCustomer(string id);
AddCustomer()
方法演示如何使用新 UriTemplate 类创建符合特定模式的新 URI。WebOperationContext()
方法用于返回将 location 标头设置为新创建客户的 URI 的 HTTP CREATED 响应。
public Customer AddCustomer(Customer customer)
{
lock (writeLock)
{
counter++;
UriTemplateMatch match = WebOperationContext.Current.IncomingRequest.UriTemplateMatch;
UriTemplate template = new UriTemplate("{id}");
customer.Uri = template.BindByPosition(match.BaseUri, counter.ToString());
customers[counter.ToString()] = customer;
WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(customer.Uri);
}
return customer;
}
服务承载
使用 WebServiceHost()
承载服务,使用 WebHttpBinding()
公开一个终结点。
using (WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("https://localhost:8000/Customers")))
{
//WebServiceHost will automatically create a default endpoint at the base address using the WebHttpBinding
//and the WebHttpBehavior, so there's no need to set it up explicitly
host.Open();
...
}
客户端
使用 WebChannelFactory
方法创建客户端以创建远程服务的通道。
using (WebChannelFactory<ICustomerCollection> cf = new WebChannelFactory<ICustomerCollection>( baseAddress ))
{
//WebChannelFactory will default to using the WebHttpBinding with the WebHttpBehavior,
//so there's no need to set up the endpoint explicitly
ICustomerCollection channel = cf.CreateChannel();
...
}
使用通道的客户端向服务器发出一系列请求,该服务器操作客户集合的状态。
输出
使用 POST 添加一些客户:
Alice 123 Pike Place https://localhost:8000/Customers/1
Bob 2323 Lake Shore Drive https://localhost:8000/Customers/2
使用 PUT 更新客户:
Charlie 123 Pike Place https://localhost:8000/Customers/1
使用 GET 检索客户的列表:
Charlie 123 Pike Place https://localhost:8000/Customers/1
Bob 2323 Lake Shore Drive https://localhost:8000/Customers/2
使用 DELETE 删除客户:
最终的客户列表:
Charlie 123 Pike Place https://localhost:8000/Customers/1
交互完成后,程序将等待按键,然后终止。
设置、生成和运行示例
若要生成 C# 或 Visual Basic .NET 版本的解决方案,请按照生成 Windows Communication Foundation 示例中的说明进行操作。
若要用单机配置或跨计算机配置来运行示例,请按照运行 Windows Communication Foundation 示例中的说明进行操作。
另请参见
任务
Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.