--- uid: web-api/overview/advanced/calling-a-web-api-from-a-net-client title: "Calling a Web API From a .NET Client (C#) | Microsoft Docs" author: MikeWasson description: "" ms.author: aspnetcontent manager: wpickett ms.date: 01/20/2014 ms.topic: article ms.assetid: df1baeef-a737-471f-a6ae-cca54cfb26d4 ms.technology: dotnet-webapi ms.prod: .net-framework msc.legacyurl: /web-api/overview/advanced/calling-a-web-api-from-a-net-client msc.type: authoredcontent --- Calling a Web API From a .NET Client (C#) ==================== by [Mike Wasson](https://github.com/MikeWasson) [Download Completed Project](https://github.com/MikeWasson/HttpClientSample) This tutorial shows how to call a web API from a .NET application, using [System.Net.Http.HttpClient.](https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx) In this tutorial, we will write an client application that consumes the following web API. | Action | HTTP method | Relative URI | | --- | --- | --- | | Get a product by ID | GET | /api/products/*id* | | Create a new product | POST | /api/products | | Update a product | PUT | /api/products/*id* | | Delete a product | DELETE | /api/products/*id* | > [!NOTE] > To learn how to implement this API on the server, using ASP.NET Web API, see [Creating a Web API that Supports CRUD Operations](../older-versions/creating-a-web-api-that-supports-crud-operations.md). For simplicity, the client application in this tutorial is a Windows console application. **HttpClient** is also supported for Windows Phone and Windows Store apps. For more information, see [Writing Web API Client Code for Multiple Platforms Using Portable Libraries](https://blogs.msdn.com/b/webdev/archive/2013/07/19/writing-web-api-client-code-for-multiple-platforms-using-portable-libraries.aspx) ## Create the Console Application In Visual Studio, create a new Windows console application and paste in the following code. [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample1.cs)] This code provides the skeleton for the application. The `Main``RunAsync` method and blocks until it completes. The reason for this approach is that most **HttpClient** methods are async, because they perform network I/O. All of the async tasks will be done inside `RunAsync`. In a console application, it's OK to block the main thread inside of `Main`. In a GUI application, you should never block the UI thread. ## Install the Web API Client Libraries Use NuGet Package Manager to install the Web API Client Libraries package. From the **Tools** menu, select **Library Package Manager**, then select **Package Manager Console**. In the Package Manager Console window, type the following command: [!code-console[Main](calling-a-web-api-from-a-net-client/samples/sample2.cmd)] ## Add a Model Class Add the following class to the application: [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample3.cs)] This class matches the data model used by the web API. We can use **HttpClient** to read a `Product` instance from an HTTP response, without having to write a lot of deserialization code. ## Create and Initialize HttpClient Add a static **HttpClient** property to the `Program` class. [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample4.cs)] > [!NOTE] > **HttpClient** is intended to be instantiated once and re-used throughout the life of an application. Especially in server applications, creating a new **HttpClient** instance for every request will exhaust the number of sockets available under heavy loads. This will result in **SocketException** errors. To initialize the **HttpClient** instance, add the following code to the `RunAsync` method: [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample5.cs)] This code sets the base URI for HTTP requests, and sets the Accept header to "application/json", which tells the server to send data in JSON format. ## Sending a GET request to retrieve a resource The following code sends a GET request for a product: [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample6.cs)] The **GetAsync** method sends the HTTP GET request. The method is asynchronous, because it performs network I/O. When the method completes, it returns an **HttpResponseMessage** that contains the HTTP response. If the status code in the response is a success code, the response body contains the JSON representation of a product. Call **ReadAsAsync** to deserialize the JSON payload to a `Product` instance. The **ReadAsync** method is asynchronous because the response body can be arbitrarily large. **HttpClient** does not throw an exception when the HTTP response contains an error code. Instead, the **IsSuccessStatusCode** property is **false** if the status is an error code. If you prefer to treat HTTP error codes as exceptions, call [HttpResponseMessage.EnsureSuccessStatusCode](https://msdn.microsoft.com/en-us/library/system.net.http.httpresponsemessage.ensuresuccessstatuscode(v=vs.110).aspx) on the response object. This method throws an exception if the status code falls outside the range 200–299. Note that **HttpClient** can throw exceptions for other reasons — for example, if the request times out. ### Using Media-Type Formatters to Deserialize When **ReadAsAsync** is called with no parameters, it uses a default set of *media formatters* to read the response body. The default formatters support JSON, XML, and Form-url-encoded data. Instead of using the default formatters, you can provide a list of formatters to the **ReadAsync** method, which is useful if you have a custom media-type formatter: [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample7.cs)] For more information, see [Media Formatters in ASP.NET Web API 2](../formats-and-model-binding/media-formatters.md) ## Sending a POST Request to Create a Resource The following code sends a POST request that contains a `Product` instance in JSON format: [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample8.cs)] The **PostAsJsonAsync** method serializes an object to JSON and then sends the JSON payload in a POST request. If the request succeeds, it should return a 201 (Created) response, with the URL of the created resources in the Location header. ## Sending a PUT Request to Update a Resource The following code sends a PUT request to update a product. [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample9.cs)] The **PutAsJsonAsync** method works like **PostAsJsonAsync**, except that it sends a PUT request instead of POST. ## Sending a DELETE Request to Delete a Resource The following code sends a DELETE request to delete a product. [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample10.cs)] Like GET, a DELETE request does not have a request body, so you don't need to specify JSON or XML format. ## Complete Code Example Here is the complete code for this tutorial. The code is very simple and doesn't include much error handling, but it shows the basic CRUD operations using **HttpClient**. [!code-csharp[Main](calling-a-web-api-from-a-net-client/samples/sample11.cs)]