40
Hands-On Lab Build RESTful APIs with WCF Web API Lab version: 1.1.0.0 Last updated: 12/6/2011

Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Hands-On LabBuild RESTful APIs with WCF Web APILab version: 1.1.0.0

Last updated: 12/6/2011

Page 2: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

CONTENTS

OVERVIEW................................................................................................................................................. 3

EXERCISE 1: CREATE A READ-ONLY SERVICE....................................................................................4Task 1 — Install NuGet Package Manager 1.5.....................................................................................4

Task 2 — Create the Visual Studio Solution.........................................................................................5

Task 3 — Define the Contact Resource................................................................................................8

Task 4 — Create the Contact Repository.............................................................................................9

Task 5 — Create the Contact Service.................................................................................................11

Task 6 — Host the Service.................................................................................................................12

Task 7 — Use the Browser to View the Contacts...............................................................................13

Task 8 — Create a Client Application.................................................................................................15

EXERCISE 2: CREATE A READ/WRITE SERVICE.................................................................................19Task 1 — Add a Method to Create New Contacts..............................................................................20

Task 2 — Add a Method to Delete Contacts......................................................................................20

Task 3 — Add a Method to Update Contacts.....................................................................................21

Task 3 — Update the Client...............................................................................................................22

EXERCISE 3: HOST THE SERVICE IN ASP.NET (OPTIONAL)..............................................................25Task 1 — Create an ASP.NET Web Project.........................................................................................25

Task 2 — Add the Contact Service Classes.........................................................................................26

Task 3 — Update the Service to Support Cache Control....................................................................26

Task 4 — Enable Routing...................................................................................................................27

Task 5 — Use the Browser to View the Contacts...............................................................................28

Task 6 — Add a JavaScript Client.......................................................................................................29

SUMMARY................................................................................................................................................ 32

APPENDIX: USING CODE SNIPPETS.....................................................................................................32

To give feedback please write to [email protected]. Copyright © 2011 by Microsoft Corporation. All rights reserved.

Page 3: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Overview

In recent years, it has become clear that HTTP is not just for serving up HTML pages. It is also a powerful platform for building Web APIs, using a handful of verbs (GET, POST, and so forth) plus a few simple concepts such as URIs and headers.

WCF Web API is a set of Windows Communication Foundation (WCF) components that simplify HTTP programming. Because it is built on WCF, Web API automatically handles the low-level transport details of HTTP. At the same time, Web API naturally exposes the HTTP programming model. In fact, one goal of Web API is to not abstract away the reality of HTTP. As a result, Web API is both flexible and easy to extend.

In this hands-on lab, you will use the WCF Web API to build a simple REST API for a contact manager application. You will also build a client to consume the API. Prior knowledge of WCF is not necessary.

The REST architectural style has proven to be an effective way to leverage HTTP — although it is certainly not the only valid approach to HTTP. The contact manager will expose the following RESTful methods.

This lab requires a basic understanding of HTTP and REST.

Action HTTP Method Relative URL

Get a list of all contacts. GET /api/contacts

Get a contact by ID GET /api/contacts/id

Create a contact POST /api/contacts

Update a contact PUT /api/contacts/id

Delete a contact DELETE /api/contacts/id

Objectives

In this hands-on lab, you will learn how to:

Implement a RESTful Web API that supports GET, POST, PUT and DELETE verbs

Write an HTTP client that consumes the API

Work with HTTP headers and status codes

Host the API in an ASP.NET application

Page 4: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Prerequisites

Microsoft Visual Studio 11 Developer Preview

Windows PowerShell (for setup scripts – already installed on Windows 7 and Windows Server 2008 R2)

Setup

Throughout the lab document, you will be instructed to insert code blocks. For your convenience, most of that code is provided as Visual Studio Code Snippets, which you can use from within Visual Studio to avoid having to add it manually.

To install the code snippets:

1. Open a Windows Explorer window and browse to the lab’s Source\Setup folder.

2. Double-click the Setup.cmd file in this folder to install the Visual Studio code snippets.

If you are not familiar with the Visual Studio Code Snippets, and want to learn how to use them, you can refer to the appendix from this document ‘Using Code Snippets’.

Exercises

This hands-on lab includes the following exercises:

1. Create a Read-Only Service

2. Create a Read/Write Service

3. Host the Service in ASP.NET

Estimated time to complete this lab: 60 minutes.

Exercise 1: Create a Read-Only Service

In this exercise, you will implement the read-only GET methods for the contact manager. You will also write a simple HTTP client to consume the service.

Task 1 — Install NuGet Package Manager 1.5

Execute this task if you do not have NuGet Package Manager installed in your Visual Studio environment.

Page 5: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

1. Run Visual Studio.

2. From the Tools menu, select Extension Manager.

3. In the Extension Manager wizard, select Online Extensions.

4. In the search box, search for the NuGet Package Manager.

Figure 1Installing NuGet Package Manager

5. Click Download.

6. Click Yes to install NuGet Package Manager.

7. Restart Visual Studio.

Alternatively, you can download NuGet Package Manager from the MSDN Visual Studio Gallery (http://visualstudiogallery.msdn.microsoft.com).

Note: Make sure to install version 1.5, which is compatible with Visual Studio 11 Developer Preview.

Task 2 — Create the Visual Studio Solution

1. Run Visual Studio with Administrator privileges.

2. From the Start page, click New Project; or from the File menu, go to New and select Project.

Page 6: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

3. Under Installed Templates in the New Project dialog box, expand Visual C#, and then click Windows.

Select the Console Application template and name the project ContactManager.

Figure 2Creating a new Console Application project

4. Add assembly references:

a. From the Project menu, select Add Reference.

b. Select the following assemblies:

System.ServiceModel

System.ServiceModel.Activation

System.ServiceModel.Web

c. Click Add.

d. Click Close.

Page 7: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 3Adding assembly references

Note: As these assemblies are not included in the client profile, the project will be retargeted to the full profile of .NET Framework 4.5.

5. Add references to the WCF Web API assemblies.

a. In Solution Explorer, right-click the project node and select Manage NuGet Packages.

Note: If this menu item does not appear, make sure that you installed NuGet Package Manager. You may need to restart Visual Studio.

b. In the left pane, select “NuGet official package source” from the Online section.

c. In the Search box, type “webapi”.

d. After the search completes, select the WebApi package and click Install.

e. Click I Accept to accept the license for the WCF Web API libraries.

f. After the package is installed, click Close.

Page 8: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 4Using NuGet to install the WebAPI assemblies

Task 3 — Define the Contact Resource

RESTful APIs are all about resources. For the Contact Manager, we will define a single resource type—the contact resource. For this lab, a contact resource will consist of a contact name plus an identifier. For example:

Contact ID Contact Name

“1” “Alice”

“2” “Bob”

In a real application, contacts would include more information, such as email address, phone number, and so on. But adding these extra fields would not really add anything to the lab, so we’ll keep things simple.

To define the contact resource, add a new Contact class to the project.

1. In Solution Explorer, select the project.

2. From the Project menu, select Add Class.

Page 9: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

3. Name the class file Contact.cs.

4. Add the public modifier to the class.

5. Add the following properties to the Contact class.

(Code Snippet – WCF Web API Lab - Ex01 - Contact Class - CS)

C#

public class Contact{ public int Id { get; set; } public string Name { get; set; }}

Task 4 — Create the Contact Repository

Our service needs a place to store contacts. For this exercise, contacts will be stored in system memory.

1. From the Project menu, select Add Class.

2. Name the class file ContactRepository.cs.

3. Add the public modifier to the class.

C#

public class ContactRepository{}

4. Add the following class implementation.

(Code Snippet – WCF Web API Lab - Ex01 - ContactRepository Class - CS)

C#

public class ContactRepository{ private int nextID = 1; private List<Contact> contacts = new List<Contact>();

public void Add(Contact contact) { if (contact == null) { throw new ArgumentNullException("contact"); } if (contact.Id == 0)

Page 10: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

{ contact.Id = this.nextID; this.nextID++; }

this.contacts.Add(contact); }

public void Delete(Contact contact) { if (contact == null) { throw new ArgumentNullException("contact"); } this.contacts.Remove(contact); }

public List<Contact> GetAll() { return this.contacts; }

public Contact GetById(int id) { return this.contacts.Find((x) => x.Id == id); }}

5. For this lesson, the contact service will be read-only, so we need to populate the repository with some names. In the ContactRepository class, add the following constructor.

(Code Snippet – WCF Web API Lab - Ex01 - ContactRepository Constructor - CS)

C#

public ContactRepository(){ this.Add(new Contact() { Name = "Alice" }); this.Add(new Contact() { Name = "Bob" }); this.Add(new Contact() { Name = "Charles" }); this.Add(new Contact() { Name = "Denise" });}

Feel free to make up your own names. Notice that the Add method overwrites the contact ID using a running counter (the nextID variable).

Page 11: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Task 5 — Create the Contact Service

In this task, you will define a service contract by using WCF WebApi. Then, you will add a service method, which will return all the contacts and a single contact by its id.

1. Add a new C# class named ContactService.

2. Add the public modifier to the class.

3. Add the following using statements.

(Code Snippet – WCF Web API Lab - Ex01 - Service Namespaces - CS)

C#

using System.Net;using System.Net.Http;using System.ServiceModel;using System.ServiceModel.Activation;using System.ServiceModel.Web;using Microsoft.ApplicationServer.Http.Dispatcher;

4. Add the [ServiceContract] attribute to the ContactService class.

C#

[ServiceContract]public class ContactService{ ...

The ServiceContract attribute defines a WCF service contract. The WCF runtime uses this attribute to bind to the service.

5. Add a static field that contains a ContactRepository instance.

(Code Snippet – WCF Web API Lab - Ex01 - Service Store - CS)

C#

[ServiceContract]public class ContactService{ private static ContactRepository store = new ContactRepository(); ...

6. Add the following methods to the class:

Page 12: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

(Code Snippet – WCF Web API Lab - Ex01 - Service Methods - CS)

C#

[WebGet(UriTemplate = "/contacts")]public List<Contact> GetAllContacts(){ return store.GetAll();}

[WebGet(UriTemplate = "/contacts/{id}")]public Contact GetContact(int id){ Contact contact = store.GetById(id); if (contact == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } return contact;}

The WebGet attribute exposes the method to clients as an HTTP GET method. The UriTemplate parameter defines the URL for the method. For example, to invoke the GetAllContacts method, the client would send and HTTP GET request to http://url/contacts/, where url is the base URL of the service. The base URL will be defined in the next task.

Task 6 — Host the Service

In this task, you will host the service locally using the HttpServiceHost class, in order to access each operation in the specified address.

1. Open the code file Program.cs.

2. Add the following using statement in order to use the HttpServiceHost class, which provides a ServiceHost to host the HTTP service.

(Code Snippet – WCF Web API Lab - Ex01 - Host Using - CS)

C#

using Microsoft.ApplicationServer.Http;

3. Add the following code to the Main method. The service of type ContactService will run in the URL and port you are specifying.

Page 13: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

(Code Snippet – WCF Web API Lab - Ex01 - Host Main - CS)

C#

static void Main(string[] args){ using (var host = new HttpServiceHost(typeof(ContactService), "http://localhost:8080/api/")) { host.Open(); Console.WriteLine("Press [enter] to Quit."); Console.ReadLine(); }}

Task 7 — Use the Browser to View the Contacts

1. Start the application: Press F5, or choose Start Debugging from the Debug menu.

Note: If you receive the following error, make sure that you started Visual Studio with administrator privileges: “HTTP could not register URL http://+:8080/api/.” If not, restart Visual Studio with administrator privileges and open the project again.

2. Open a browser window.

3. In the address bar, type http://localhost:8080/api/contacts/ and press Enter. You should see an XML representation of the contact list.

Page 14: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 5Contact list displayed in the browser window

4. In the address bar, type http://localhost:8080/api/contacts/1 and press Enter. You should see an XML representation of a single contact.

5. Close the browser window and press Enter in the console application to stop debugging.

Discussion

To expose a GET method from a WCF Web API service, just add the WebGet attribute to a public method of the service class. For example, the GetAllContacts method was defined as follows:

C#

[WebGet(UriTemplate = "/contacts")]public List<Contact> GetAllContacts(){ return Store.GetAll();}

The UriTemplate parameter gives the URI of the HTTP GET method, relative to the base path listed in the routing information (see Task 2).

Page 15: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

The base path for our service is http://localhost:8080/api, so the URI template “/contacts” corresponds to http://localhost:8080/api/contacts/. If a client requests this URI, the GetAllContacts method is invoked.

The URI template can also be parameterized, as shown in the GetContact method:

C#

[WebGet(UriTemplate = "/contacts/{id}")]public Contact GetContact(int id){ ...

The id parameter within the curly braces is bound to the method parameter of the same name. For example, if the client requests http://localhost:8080/api/contacts/1, the GetContact method is invoked with a value of 1 for the id parameter.

Notice that both of these methods return CLR types. The Web API automatically serializes the return value. The default serialization format is XML. In the next exercise, you’ll see how a client can request JSON by providing an Accept header in the HTTP request.

Task 8 — Create a Client Application

In this task, you will create a client application that will use the WCF WebApi service that you have worked on.

1. Add a new console application to the solution.

a. From the File menu, select Add and then New Project.

b. Expand the Visual C# project types and select Windows, then Console Application.

c. Name the project ContactClient.

2. Change the target framework to .NET Framework 4.5.

a. In Solution Explorer, right-click the ContactClient project and select Properties.

b. In the Target framework dropdown list, select .NET Framework 4.5.

c. Click Yes.

Page 16: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 6Setting the target framework

3. Add references to the WCF Web API assemblies.

a. In Solution Explorer, right-click the ContactClient project and select Manage NuGet Packages.

b. In the pane on the left, select Recent Packages.

c. Select WebApi.

d. Click Install.

e. Click Close.

Note: These steps assume that you already installed the WebApi package in Task 2.

4. Add a reference to the ContactManager project:

a. From the Project menu, select Add Reference.

b. Select Solution.

c. Click Add.

d. Click Close.

Page 17: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 7 Adding a reference to the ContactManager project

5. Open Program.cs located under the ContactClient project. Add the following using statements.

(Code Snippet – WCF Web API Lab - Ex01 - Client Namespaces - CS)

C#

using System.Net.Http;using System.Web;using ContactManager;

6. Add the following static method.

(Code Snippet – WCF Web API Lab - Ex01 - ListAllContacts - CS)

C#

private static void ListAllContacts(HttpClient client){ client.GetAsync("api/contacts") .ContinueWith(r => { Console.WriteLine("List Status: {0}", r.Result.StatusCode);

if (r.Result.IsSuccessStatusCode) { r.Result.Content.ReadAsAsync<List<Contact>>() .ContinueWith(l => { foreach (Contact c in l.Result)

Page 18: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

{ Console.WriteLine("{0}: {1}", c.Id, c.Name); } }); } });}

7. Add the following code to the Main method.

(Code Snippet – WCF Web API Lab - Ex01 - Client Main - CS)

C#

static void Main(string[] args){ using (HttpClient client = new HttpClient()) { client.BaseAddress = new Uri("http://localhost:8080/");

ListAllContacts(client);

Console.WriteLine("Press [enter] to quit."); Console.ReadLine(); }}

8. Press F5 to start debugging the ContactManager project.

9. Run the ContactClient client project:

a. In Solution Explorer, right-click the ContactClient project.

b. Select Debug and then Start New Instance.

c. The console application should run, displaying a list of contacts.

Figure 8Running the ContactClient application

10. Press Enter in both console applications to stop debugging.

Page 19: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Discussion

The HttpResponseMessage object represents an HTTP response. You can use it to get the status code, headers, and message body of the request. HttpResponseMessage also has a generic ReadAsAsync<T> method that deserializes the message body into a CLR type, so that you don’t have to worry about serialization formats.

If you want to see the message body in its original form, replace the if statement with the following:

(Code Snippet – WCF Web API Lab - Ex01 - ReadAsString - CS)

C#

if (r.Result.IsSuccessStatusCode){ r.Result.Content.ReadAsStringAsync() .ContinueWith(s => { Console.WriteLine(s.Result); });}

Now if you re-run the client, it will output the following:

XML

<?xml version="1.0" encoding="utf-8"?><ArrayOfContact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Contact><Id>1</Id><Name>Alice</Name></Contact><Contact><Id>2</Id><Name>Bob</Name></Contact><Contact><Id>3</Id><Name>Charles</Name></Contact><Contact><Id>4</Id><Name>Denise</Name></Contact></ArrayOfContact>

As you can see, the web service defaulted to XML serialization. The client can request JSON format by adding an Accept header with the value “application/json”:

C#

using (HttpClient client = new HttpClient()){ client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); client.BaseAddress = new Uri("http://localhost:8080/");

ListAllContacts(client);

Now if you run the application, the HTTP response contains the following:

JSON

Page 20: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

[{"Id":"1","Name":"Alice"},{"Id":"2","Name":"Bob"},{"Id":"3","Name":"Charles"},{"Id":"4","Name":"Denise"}]

Exercise 2: Create a Read/Write Service

In Exercise 1, you created a read-only service. In this exercise, you will add methods to create, delete and update contacts.

Task 1 — Add a Method to Create New Contacts

1. Open the ContactService.cs code file and add the following method to the ContactService class.

(Code Snippet – WCF Web API Lab - Ex02 - CreateContact - CS)

C#

[WebInvoke(UriTemplate = "/contacts", Method = "POST")]public HttpResponseMessage<Contact> CreateContact(HttpRequestMessage<Contact> request){ if (request == null) { throw new ArgumentNullException("request"); } HttpResponseMessage<Contact> response = null; var task = request.Content.ReadAsAsync(); task.Wait();

Contact contact = task.Result; if (contact == null) { response = new HttpResponseMessage<Contact>(HttpStatusCode.BadRequest); } else { store.Add(contact); // Add the new contact to the repository. response = new HttpResponseMessage<Contact>(contact, HttpStatusCode.Created); // status = 201

response.Headers.Location = new Uri(request.RequestUri, contact.Id.ToString()); }

Page 21: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

return response;}

Task 2 — Add a Method to Delete Contacts

1. To enable the user to delete a contact, add the following method to the ContactService class.

(Code Snippet – WCF Web API Lab - Ex02 - DeleteContact - CS)

C#

[WebInvoke(UriTemplate = "/contacts/{id}", Method = "DELETE")]public Contact DeleteContact(int id){ Contact contact = store.GetById(id); if (contact == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } store.Delete(contact); return contact;}

Task 3 — Add a Method to Update Contacts

1. To enable the user to update a contact, add the following method to the ContactService class.

(Code Snippet – WCF Web API Lab - Ex02 - UpdateContact - CS)

C#

[WebInvoke(UriTemplate = "/contacts/{id}", Method = "PUT")]public HttpResponseMessage<Contact> UpdateContact(int id, HttpRequestMessage<Contact> request){ Contact existingContact = store.GetById(id); if (existingContact == null) { throw new HttpResponseException(HttpStatusCode.NotFound); }

if (request == null) { throw new ArgumentNullException("request"); }

HttpResponseMessage<Contact> response = null;

Page 22: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

var task = request.Content.ReadAsAsync(); task.Wait();

Contact updatedContact = task.Result; if (updatedContact == null) { response = new HttpResponseMessage<Contact>(HttpStatusCode.BadRequest); } else { store.Delete(existingContact); // Delete old contact store.Add(updatedContact); // Add the updated contact to the repository. response = new HttpResponseMessage<Contact>(updatedContact, HttpStatusCode.OK); // status = 200

response.Headers.Location = new Uri(request.RequestUri, updatedContact.Id.ToString()); }

return response;}

Task 3 — Update the Client

In this task, you will update the client to consume the new methods you just created in the Contacts service.

1. Add a Sleep call in the GetAllContacts function from the ContactService class.

C#

[WebGet(UriTemplate = "/contacts")]public List<Contact> GetAllContacts(){ System.Threading.Thread.Sleep(2000); return store.GetAll();}

Note: You need this to make the operation last longer to complete its execution when all the previous operations have completed and see the list when updated.

2. In Solution Explorer, go to the ContactClient project and open Program.cs

3. Add the following using

Page 23: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

(Code Snippet – WCF Web API Lab - Ex02 - ContactClient Using - CS)

C#

using System.Net.Http.Formatting;

4. Add the following methods.

(Code Snippet – WCF Web API Lab - Ex02 - Client - CS)

C#

private static void AddContact(HttpClient client, string name){ Contact contact = new Contact() { Name = name };

client.PostAsync("api/contacts/", new ObjectContent<Contact>(contact, XmlMediaTypeFormatter.DefaultMediaType)) .ContinueWith(r => { Console.WriteLine("Add Status: {0}", (int)r.Result.StatusCode); });}

private static void DeleteContact(HttpClient client, int id){ client.DeleteAsync(string.Format("api/contacts/{0}", id)) .ContinueWith(r => { Console.WriteLine("Delete Status {0}", (int)r.Result.StatusCode); });}

private static void UpdateContact(HttpClient client, int id, string newName){ Contact contact = new Contact() { Id = id, Name = newName }; client.PutAsync(string.Format("api/contacts/{0}", id), new ObjectContent<Contact>(contact, XmlMediaTypeFormatter.DefaultMediaType)) .ContinueWith(r => { Console.WriteLine("Update Status: {0}", (int)r.Result.StatusCode); });}

5. Add the following code to the Main method.

Page 24: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

(Code Snippet – WCF Web API Lab - Ex02 - Client Main - CS)

C#

static void Main(string[] args){ using (HttpClient client = new HttpClient()) { client.BaseAddress = new Uri("http://localhost:8080/");

DeleteContact(client, 1); AddContact(client, "Edgar"); UpdateContact(client, 3, "Charly");

ListAllContacts(client);

Console.WriteLine("Press [enter] to quit."); Console.ReadLine(); }}

6. Press F5 to start debugging the ContactManager project.

7. Run the ContactClient client project:

a. In Solution Explorer, right-click the ContactClient project.

b. Select Debug and then Start New Instance.

c. The console application should run, displaying a list of contacts.

Figure 9Running the ContactClient application

8. Press Enter in both console applications to stop debugging.

Discussion

POST, PUT, and DELETE methods are defined using the WebInvoke attribute, with the HTTP method given in the Method parameter. For example, to define a POST method, set Method equal to “POST”:

Page 25: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

C#

[WebInvoke(UriTemplate = "{id}", Method = "POST")]

Similarly for a DELETE method:

C#

[WebInvoke(UriTemplate = "/contacts/{id}", Method = "DELETE")]

… and for a PUT method:

C#

[WebInvoke(UriTemplate = "/contacts/{id}", Method = "PUT")]

Exercise 3: Host the Service in ASP.NET (Optional)

In the previous exercises, the service was hosted in a console application. In this exercise, you will host the service in IIS using ASP.NET. You will also create a web page that consumes the service using JavaScript.

Task 1 — Create an ASP.NET Web Project

1. Open Visual Studio 11.

2. From the Start page, click New Project; or from the File menu, go to New and select Project.

3. Under Installed Templates in the New Project dialog box, expand Visual C#, and then click Web.

4. Select the ASP.NET Web Application template and name the project ContactManagerWeb.

5. Add references to the WCF Web API assemblies.

a. In Solution Explorer, right-click the ContactManagerWeb project and select Manage NuGet Packages.

Note: If this menu item does not appear, make sure that you installed NuGet Package Manager as instructed in Exercise 1. You may need to restart Visual Studio.

b. In the pane on the left, select Recent Packages, and then click the WebApi package.

c. On WebApi, click Install.

Page 26: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

d. Click I Accept to accept the license for the WCF Web API libraries.

e. Click Close.

Task 2 — Add the Contact Service Classes

1. Add the following classes to the project, located in the folder WCFWebAPI\Source\CS\Assets\Ex3-ASPNETHosting.

Note: These files are similar to the ones you’ve been using in the previous exercise, but adapted to Exercise 3 namespace.

◦ Contact

◦ ContactRepository

◦ ContactService

Task 3 — Update the Service to Support Cache Control

1. Open the ContactService.cs code file.

2. Replace the existing GetAllContacts method with the following implementation. In this version, the method returns an HttpResponseMessage object, which represents the HTTP response. The method sets the cache-control header to “no-cache” to disable caching.

(Code Snippet – WCF Web API Lab - Ex03 - GetAllContacts - CS)

C#

[WebGet(UriTemplate = "/contacts")]public HttpResponseMessage<List<Contact>> GetAllContacts(){ var contacts = store.GetAll(); var response = new HttpResponseMessage<List<Contact>>(contacts); response.Headers.CacheControl = new CacheControlHeaderValue() { NoStore = true }; return response;}

3. Replace the existing GetContact method with the following implementation.

(Code Snippet – WCF Web API Lab - Ex03 - GetContact - CS)

C#

[WebGet(UriTemplate = "/contacts/{id}")]

Page 27: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

public HttpResponseMessage<Contact> GetContact(int id){ Contact contact = store.GetById(id); if (contact == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } var response = new HttpResponseMessage<Contact>(contact); response.Headers.CacheControl = new CacheControlHeaderValue() { NoCache = true }; return response;}

Task 4 — Enable Routing

The purpose of this task is to associate URIs of the form “http://localhost:[port]/api/...” with the ContactManager service, so that IIS correctly routes HTTP requests to the service.

1. Open the Web.config file.

2. Add the following elements under the root configuration element:

(Code Snippet – WCF Web API Lab - Ex03 - Web.config)

XML

</system.web> <!-- Ensure the UrlRoutingModule --> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </modules> </system.webServer>

3. In Solution Explorer, double-click Global.asax to open the Global.asax.cs code-behind file.

4. Add the following using statements.

(Code Snippet – WCF Web API Lab - Ex03 – GlobalAsax Namespaces - CS)

C#

using System.Web.Routing;using System.ServiceModel.Activation;using Microsoft.ApplicationServer.Http.Activation;

Page 28: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

5. Add the following code to the Application_Start method.

(Code Snippet – WCF Web API Lab - Ex03 - Application_Start - CS)

C#

void Application_Start(object sender, EventArgs e){ // Code that runs on application startup RouteTable.Routes.Add(new ServiceRoute("api", new HttpServiceHostFactory(), typeof(ContactService)));}

Note: ServiceRoute takes a path for the API which will be appended to the IIS base address as well as the host factory to use and the type of the API. In this case we specified “api” thus it will be hosted at “http://localhost:[port]/api”. The reasoning for this is to avoid conflicts between MVC routes as this route will always capture all traffic that starts with “api”.

Task 5 — Use the Browser to View the Contacts

1. Start debugging the application: Press F5, or choose Start Debugging from the Debug menu.

2. Visual Studio will start IIS Express and open a browser window to the home page.

3. In the address bar of the browser, type http://localhost:[port]/api/contacts/ and press Enter. You should see an XML representation of the contact list.

Note: Replace the [port] placeholder with the port number where the application is currently running.

Page 29: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 10Running the solution and displaying the contact list in the browser

4. Close the browser window.

Task 6 — Add a JavaScript Client

1. Right click the project and select Add Existing Item. In the WCFWebAPI\Source\CS\Assets\Ex3-ASPNETHosting folder select the Default.aspx file. In the Destination File Exists dialog, press Yes to replace the existing file with the one you are adding.

2. Open the Default.aspx file.

3. Within the BodyContent control, add a script block with the following code to get the contacts list.

JavaScript

... </div>

<script type="text/javascript">

var selected = null;

function getContacts() { $.getJSON("api/contacts",

Page 30: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

function (data) {

// Clear the <ul> element. $('#contacts').empty();

// Loop through the list of contacts. $.each(data, function (key, val) { $('<li/>', { html: val.Name }) // Add a list entry with the contact name .data({ contact: val }) // Associate the contact with the <li> element .appendTo($('#contacts')); // Append the name to the list. });

// Set an onclick handler for each list entry. $("#contacts > li").click(function () { selected = $(this).data('contact'); // Get the contact. $("#contacts li").removeClass("active"); // Remove highlight from previous selection. $(this).addClass("active"); // Highlight current selection. }); }); }

$(document).ready(function () { getContacts(); });

</script>

</asp:Content>

The getContacts function calls getJSON, which is a jQuery function, to submit an Ajax request to the service. One of the parameters to getJSON is a callback function that is called if the request succeeds. Within the callback function, we are adding the contacts to a <ul> element in the document.

4. Add a function to create a new contact.

(Code Snippet – WCF Web API Lab - Ex03 - AddContact - JS)

JavaScript

function addContact() {

Page 31: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

var name = $.trim($('#contactName').val());

if (!name) { alert("Please enter the contact name."); return; };

var str = JSON.stringify({ Name: name });

$.ajax({ type: "POST", contentType: "application/json", url: "api/contacts", data: str, dataType: "json", success: getContacts });

// Clear the input field $('#contactName').val("");}

This function gets the name from the text input and then calls the jQuery ajax function to submit a POST request.

5. Add a function to delete new contact.

(Code Snippet – WCF Web API Lab - Ex03 - DeleteContact - JS)

JavaScript

function deleteContact() { if (selected) { $.ajax({ type: "DELETE", url: "api/contacts/" + selected.Id, success: getContacts });

selected = null; }}

This function is similar to the previous function, except that it uses DELETE instead of POST.

6. Run the application. After the page loads, it will asynchronously get the list of contacts. This may take a few seconds as the service initially starts.

Page 32: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 11Running the ASP.NET application

7. Select a contact name and click Delete. The list should refresh and show that the name was deleted.

8. In the Add Contact input field, type a new contact name (such as “Edgar”) and click the Add Contact button. The list should refresh and show the name that was added.

9. Close the browser window.

Summary

By completing this Hands-On Lab, you have learned how to create a web API that supports HTTP GET, POST, PUT and DELETE methods, using WCF Web API and how to consume it from a console application. You have also seen how to host your API in ASP.NET. Finally, you have seen two different ways for a client to access the API, using both C# and JavaScript with AJAX.

Appendix: Using Code Snippets

Page 33: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

With code snippets, you have all the code you need at your fingertips. The lab document will tell you exactly when you can use them, as shown in the following figure.

Figure 12Using Visual Studio code snippets to insert code into your project

To add a code snippet using the keyboard (C# only)

1. Place the cursor where you would like to insert the code.

2. Start typing the snippet name (without spaces or hyphens).

3. Watch as IntelliSense displays matching snippets' names.

4. Select the correct snippet (or keep typing until the entire snippet's name is selected).

5. Press the Tab key twice to insert the snippet at the cursor location.

Figure 13Start typing the snippet name

Page 34: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 14Press Tab to select the highlighted snippet

Figure 15Press Tab again and the snippet will expand

To add a code snippet using the mouse (C#, Visual Basic and XML)

1. Right-click where you want to insert the code snippet.

2. Select Insert Snippet followed by My Code Snippets.

3. Pick the relevant snippet from the list, by clicking on it.

Figure 16Right-click where you want to insert the code snippet and select Insert Snippet

Page 35: Build RESTful APIs with WCF Web APIaz12722.vo.msecnd.net/.../labs/wcfwebapi1-1-0-0/Lab.docx · Web viewBuild RESTful APIs with WCF Web API Description In recent years, it has become

Figure 17Pick the relevant snippet from the list, by clicking on it