高级 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 方法在外部公开的基本的 CreateReadUpdateDelete 操作。

服务协定和实现

在本示例中,服务实现在基本 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

交互完成后,程序将等待按键,然后终止。

设置、生成和运行示例

  1. 请确保已经执行了 Windows Communication Foundation 示例的一次性安装过程

  2. 若要生成 C# 或 Visual Basic .NET 版本的解决方案,请按照生成 Windows Communication Foundation 示例中的说明进行操作。

  3. 若要用单机配置或跨计算机配置来运行示例,请按照运行 Windows Communication Foundation 示例中的说明进行操作。

另请参见

任务

基本 Web 编程模型示例

Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.