Getting Started: Web API Enhancements

Learning objectives

In this quick start you will learn how to leverage the WCF Web API Enhancements* to simplify the implementation of a Web API.

How to simplify adding routes and configuration for a Web API

How to use conventions to enable HTTP POST, PUT and DELETE methods on an API.

How to enable browser HTML forms to POST to an API.

How to implement asynchronous service operations using Task/Task<T>

*Note: The Web API Enhancements are a collection of prototype features that simplify and add on to the core Web API features. Your feedback on these enhancements is greatly appreciated!

Pre-requisites

Visual Studio 2010 / Visual Studio 2010 SP1

ASP.NET MVC 3**

**Note: Web API does not requires ASP.NET MVC, it supports supports multiple hosting configurations including self-host, IIS and ASP.NET (both MVC and Web Forms). This quick start however show show to host in ASP.NET MVC 3.

Scenario

For this quick start the scenario will be to simplify the implementation of an existing Web API using Web API Enhancements

1 – Extract the starter code

To begin the quick start first extract the starter code / end code available here. Once the starter code is extracted, open the solution in the “Start” folder.

2 – Use MapServiceRoute<T>

The implementation in the Start solution adds a ServiceRoute to the ASP.NET routes table to enable hosting of the Web API. The ServiceRoute must be constructed with the HttpServiceHostFactory and the Web API type to enable hosting of the Web API. Configuration
data for the Web API is passed to the HttpServiceHostFactory.

Web API Enhancements adds a convenience MapServiceRoute<T> extension method that takes care of adding and configuring the HttpServiceHostFactory. By default MapServiceRoute<T> uses WebApiRoute instead of ServiceRoute, which enables action link
generation from ASP.NET MVC controllers in the same application. MapServiceRoute<T> also provides a convenient generic type parameter for specifying the Web API type.

Double-click on the Global.asax file in the project

Modify the RegisterRoutes method to replace ServiceRoute code with the following call to MapServiceRoute<T>

routes.MapServiceRoute<ContactsApi>("api/contacts", config);

Build and run the solution (F5) to verify that the Web API is still functional

3 – Use WebApiConfiguration

The Web API is configured by passing in an HttpConfiguration instance when creating the service route. For example, the HttpConfiguration is used to enable the Web API test client. Web API Enhancements extends HttpConfiguration to enable simplifying conventions
and to add support for additional formats, like form URL encoded data. The MapServiceRoute<T> extension method uses WebApiConfiguration by default, but we still want to enable the Web API test client. We will modify the code to use WebApiConfiguration
instead of HttpConfiguration.

In the RegisterRoutes method change the type of the configuration instance to be WebApiConfiguration

var config = new WebApiConfiguration() { EnableTestClient = true };

Build and run the solution (F5)

4 – Use conventions to specify supported HTTP methods

The WebApiConfiguration enables a convention that allows you to specify the HTTP method for an operation using a prefix on the operation name (ex. PostXxx, PutXxx, DeleteXxx). Using WebApiConfiguration also changes the default UriTemplate to be “”
instead of the name of the operation.

Open ContactsApi.cs

Modify the WebGetAttribute on the Get operation to remove the UriTemplate

When the page loads, enter “http://localhost:9000/contacts/create” to load the create contact page.

Enter “New Contact3” for the contact name and press "Add”

The created contact is returned.

6 – Implement asynchronous operations using Task/Task<T>

Using WebApiConfiguration also enables support for implementing asynchronous operations using Task or Task<T>. Here we will add an asynchronous operation to our Web API that calls a another Web API asynchronously and then processes and returns the
result. We will add a new Web API for getting status messages for contacts and then add an operation to the ContactsApi that aggregates the status for all added contacts.

right click on the Resources folder and choose Add->Class. Enter Status as the class name

The StatusApi maintains a single Status instance per contact indexed by the Contact ID. The StatusApi provides operations for getting the all of the posted status information, getting the status for a specific contact, and posting a new status for a given
contact.

Double-click on the global.asax file

In the RegisterRoutes method specify the configuration instance as the default configuration for all Web APIs in this application using the SetDefaultHttpConfiguration extension method

The GetStatusAsync operation uses the HttpClient to asynchronously request status data from the status Web API for each contact in the repository. The ContinueWhenAll method Creates a continuation Task that will be started upon the completion of the requests.
The continuation code filters the responses to just the ones that completed successfully. Because the response type is Task<IQueryable<T>> the GetStatusAsync operation supports OData queries.

Build and run the solution (F5)

Browse to the Web API test client for the status Web API by browsing to http://localhost:9000/api/status/test

Click the status resource in the Resources view

Change the HTTP method to be POST

Select the JSON tab and add the following content to the Request body

{ "ContactId": 1, "Message": "Falling in love with WCF Web API!" }

Click the Send button

The status for contact 1 was successfully added.

Post a few more status updates for other contacts

{ "ContactId": 2, "Message": "There's a gorilla in my bed!" }

{ "ContactId": 3, "Message": "I think I'll move to Australia" }

Browse to http://localhost:9000/api/contacts/status to retrieve the status updates for all of the contacts

The status updates for the contacts were successfully retrieved asynchronously

Summary

In this quick start we learned how to use Web API Enhancements to do the following:

How to simplify adding routes and configuration for a Web API

How to use conventions to enable HTTP POST, PUT and DELETE methods on an API.

Looks like version 0.6 broke the GetStatusAsync() method in step 6 of this walkthrough. I'm guessing the sync methods being removed from HttpClient in 0.6 has something to do with it, but I'm not sure. Anyone out there have any idea how to update GetStatusAsync() in the sample to make it play nicely with 0.6?