How to use System.Net.Http.HttpClient handlers (Windows Store apps using C#/VB and XAML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

Use the System.Net.Http.HttpClientHandler class with the System.Net.Http.HttpClient class in the System.Net.Http namespace to send a GET request to a web service and retrieve the response.

Note  The System.Net.Http and System.Net.Http.Headers namespace might not be available in future versions of Windows for use by Windows Store apps. Starting with Windows 8.1 and Windows Server 2012 R2, use Windows.Web.Http.HttpClient in the Windows.Web.Http namespace and the related Windows.Web.Http.Headers and Windows.Web.Http.Filters namespaces instead for Windows Store apps.

 

Classes in the System.Net.Http namespace provide a programming interface for modern HTTP apps. The System.Net.Http namespace and the related System.Net.Http.Headers namespace provide HTTP client components that allow users to consume modern web services over HTTP.

The System.Net.Http.HttpClient class is used to send and receive basic requests over HTTP. It provides a base class for sending HTTP requests and receiving HTTP responses from a resource identified by a URI. This class can be used to send a GET, PUT, POST, DELETE, and other requests to a web service. Each of these requests is sent as an asynchronous operation.

The System.Net.Http.HttpClientHandler class is the default message handler for System.Net.Http.HttpClient. The System.Net.Http.HttpClientHandler class, and classes derived from it, enables developers to configure a variety of options on an HTTP request ranging from proxies to authentication.

The System.Net.Http.HttpResponseMessage class represents an HTTP response message received from an HTTP request. HTTP messages are defined in RFC 2616 by the IETF.

The System.Net.Http.HttpContent class is a base class that represents an HTTP entity body and content headers. In this case, System.Net.Http.HttpContent is used to represent the HTTP response.

What you need to know

Technologies

Prerequisites

The following examples in this topic are provided in C# using the .NET Framework 4.5. A basic understanding of HTTP requests as detailed in RFC 2616 is helpful in understanding this sample.

To make HTTP requests in a Windows Runtime app using C#/VB and XAML, see How to connect to an HTTP server using Windows.Web.Http.HttpClient. To make HTTP requests in a Windows Runtime app using C++ and XAML, see How to connect to an HTTP server using Windows.Web.Http.HttpClient and How to connect using XML HTTP Extended Request and IXMLHTTPRequest2.

To make HTTP requests in a Windows Runtime app using JavaScript and HTML, see Connecting to web services (HTML).

Instructions

Step 1: Create a new project

  1. Open Microsoft Visual Studio 2013 and select New Project from the File menu.
  2. In the list of templates, choose Visual C#.
  3. Under the section, choose Store apps.
  4. Under the section, select Windows apps and then select Blank Application.
  5. Name the application HttpClientHandlerSample and click OK.

Step 2: Set capabilities to enable network access

You need to set network capabilities for your app to enable access to a private home or work network and to the Internet. For this app, you would need to enable network capabilities since the client is connecting to web services.

For an app using System.Net.Http.HttpClient or System.Net.Http.HttpClientHandler to connect to a web service on a different computer, the app would need network capabilities set. If the app needs to be able to connect as a client to a web services on the Internet, then the Internet (Client) capability is needed. If the app needs to be able to connect as a client to web services on a private home or work network, then the Private Networks (Client & Server) capability is needed.

If the web service is running on the same computer as the app, this would require loopback access. Apps developed in Microsoft Visual Studio 2012 will automatically be registered as being exempt from the loopback restrictions. For more information, see How to enable loopback and debug network isolation.

For more information on network access, see How to configure network isolation capabilities.

The steps below are not needed for this sample if the web service is on the local computer. These steps are needed to set network capabilities for the app if it accesses a web service on the Internet or on a private or work network.

  1. Use Visual Studio 2012 to open the package.appxmanifest file.
  2. Select the Capabilities tab.
  3. Select the Internet (Client) and Private Networks (Client & Server) capabilities.
  4. Save and close the manifest file.

Step 3: Add XAML UI

  • In this section, we define the app layout in XAML to specify the size and position of each object in the app. We complete the UI for the app by adding controls and content to display data.

    This sample uses simple XAML UI elements that include the following:

    • A horizontal StackPanel that contains a TextBlock for a label, a TextBox for the input URI address, and a Button used to start the asynchronous request.
    • A horizontal StackPanel that contains a TextBlock for a label and a TextBox for the current status. This is where status and error messages will be displayed.

    A Grid where the output received from the web service is displayed. In this sample, the result of the HTTP GET operation is displayed using a WebView to render the HTML markup.

    Open the cs folder. Open the existing blankPage.html file and rename the file to MainPage.xaml. Add the following UI elements to this file.

    <Page
        x:Class="HttpClientHandlerSample.BlankPage"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:HttpClientHandlerSample"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
            <StackPanel Orientation="Vertical">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="URI Address:" FontSize="16" Height="20"  Margin="15,0,0,0" />
                    <TextBox x:Name="InputAddress" Text="https://www.contoso.com" FontSize="16" Height="20" Margin="15,0,0,0" />
                    <Button Content="Start" Click="Start_Click" Margin="280,0,0,0" />
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Status:" FontSize="16" Height="20" Margin="15,0,0,0" />
                    <TextBox x:Name="StatusText" Text="Idle" FontSize="16" Height="Auto" TextWrapping="Wrap" Margin="15,0,0,0" />
                </StackPanel>
                <Grid 
                    Grid.Column="1" Margin="15,0,0,0">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <WebView x:Name="OutputView" MinWidth="300"  MinHeight="300" Margin="15,15,15,15"  />
                </Grid>    
            </StackPanel>
         </Grid>
    </Page>
    

Step 4: Create the HttpClientHandler, send the GET request, and retrieve the response

The code below first creates a System.Net.Http.HttpClientHandler object. A property is set on the object and a System.Net.Http.HttpClient object is created using the System.Net.Http.HttpClientHandler.

  1. First create the System.Net.Http.HttpClientHandler object. Set the AllowAutoRedirect property to false. This is an example of how System.Net.Http.HttpClientHandler properties can be used to set options on the HTTP request.

    The AllowAutoRedirect property indicates if requests made by the System.Net.Http.HttpClientHandler object should follow redirection responses. The default value for this property is true. If this property is set to false, then requests from the web service to redirect the request will not be followed.

    Then create the System.Net.Http.HttpClient object using the System.Net.Http.HttpClientHandler object. We also set two properties on the System.Net.Http.HttpClient object. The default size of the HttpClient.MaxResponseContentBufferSize property is the maximum size for an integer. To limit the amount of data the app accepts as a response from the web service , we set this property to a smaller value.

    By default, no user-agent header is sent with the HTTP request to the web service by the System.Net.Http.HttpClient object. Some HTTP servers, including some Microsoft web servers, require that a user-agent header be included with the HTTP request sent from the client and return an error if no header is present. A user-agent header is added using the HttpClient.DefaultRequestHeaders property to avoid these errors.

    Open the cs folder. Open the MainPage.cs file and add the following code to the file.

        private HttpClient httpClient;
        private HttpClientHandler handler;
    
        public BlankPage()
        {
            this.InitializeComponent();
            handler = new HttpClientHandler();
            handler.AllowAutoRedirect=false; 
    
            httpClient = new HttpClient(handler);
    
            // Limit the max buffer size for the response so we don't get overwhelmed
            httpClient.MaxResponseContentBufferSize = 256000;
            // Add a user-agent header
            httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
        }
    
  2. Send the GET request and retrieve the response.

    Most of the work is done in the click handler for the Start Button. When this button is clicked, the text in the StatusText and OutputView UI elements is updated, then the input URI address is used to send the HTTP GET request and await the response. If an error or exception occurs, the result is displayed in the StatusText UI element. If no errors occur, the response from the web service is displayed in the OutputView UI element.

    Using the await keyword in C# and Visual Basic, the code for sending the GET request and retrieving the response asynchronously is similar to the code we would use to complete this operation synchronously. You can use the await keyword only if the method is defined as async.

    The HttpResponseMessage.EnsureSuccessStatusCode method throws an exception if the web server returned an HTTP error status code. Use a try/catch block for any exceptions and print out the exception message in the StatusText UI element if an error occurs. In the try block, print the status and response returned by the web service.

    The HttpResponseMessage.Content property represents the content of the HTTP response. The HttpContent.ReadAsStringAsync method writes the HTTP content to a string as an asynchronous operation.

            private async void Start_Click(object sender, RoutedEventArgs e)
            {
                try
                {
                    string responseBodyAsText;
                    OutputView.NavigateToString("");
                    StatusText.Text = "Waiting for response ...";
    
                    HttpResponseMessage response = await httpClient.GetAsync(InputAddress.Text);
                    response.EnsureSuccessStatusCode();
    
                    StatusText.Text = response.StatusCode + " " + response.ReasonPhrase + Environment.NewLine;
                    responseBodyAsText = await response.Content.ReadAsStringAsync();
                    OutputView.NavigateToString(responseBodyAsText);
                }
                catch (HttpRequestException hre)
                {
                    StatusText.Text = hre.ToString();
                }
                catch (Exception ex)
                {
                    // For debugging
                    StatusText.Text = ex.ToString();
                }
            }
    

Remarks

In this topic we reviewed how to use the System.Net.Http.HttpClientHandler in conjunction with the System.Net.Http.HttpClient class to send a GET request to a web service and retrieve the response using the System.Net.Http.HttpResponseMessage and System.Net.Http.HttpContent classes. The System.Net.Http.HttpClientHandler allowed the app to set options on the HTTP request.

There are several HTTP message handlers that can be used with the System.Net.Http.HttpClient class.

HttpClientHandler sample

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/p/?linkid=234238

namespace HttpClientHandlerSample
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class BlankPage : Page
    {
        private HttpClient httpClient;
        private HttpClientHandler handler;

        public BlankPage()
        {
            this.InitializeComponent();
            handler = new HttpClientHandler();
            handler.AllowAutoRedirect=false; 

            httpClient = new HttpClient(handler);
            // Limit the max buffer size for the response so we don't get overwhelmed

            httpClient.MaxResponseContentBufferSize = 256000;
            // Add a user-agent header
            httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private async void Start_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string responseBodyAsText;
                OutputView.NavigateToString("");
                StatusText.Text = "Waiting for response ...";

                HttpResponseMessage response = await httpClient.GetAsync(InputAddress.Text);
                response.EnsureSuccessStatusCode();

                StatusText.Text = response.StatusCode + " " + response.ReasonPhrase + Environment.NewLine;
                responseBodyAsText = await response.Content.ReadAsStringAsync();
                OutputView.NavigateToString(responseBodyAsText);
            }
            catch (HttpRequestException hre)
            {
                StatusText.Text = hre.ToString();
            }
            catch (Exception ex)
            {
                // For debugging
                StatusText.Text = ex.ToString();
            }
        }
    }
}

Other resources

Connecting to web services

How to configure network capabilities

How to connect using System.Net.Http.HttpClient

How to enable loopback and debug network isolation

How to secure System.Net.Http.HttpClient connections

Troubleshooting and debugging network connections

Reference

System.Net.Http

System.Net.Http.Headers

Windows.Web.Http

Windows.Web.Http.Filters

Windows.Web.Http.Headers

Samples

HttpClient Sample