Share via


Using WebClient and HttpWebRequest

The WebClient and HttpWebRequest classes can both be used for retrieving data from a Web service. WebClient is most useful for one-time retrieval of data from a Web service, or downloading remote resources (for more information on this see, "Downloading Content on Demand") and I think, is somewhat easier to use. HttpWebRequest is perhaps a bit less user-friendly, but will enable you to set headers and generally offers more control over a Web service request.

The following code demonstrates how to make the same request using both classes. I’ve set up a simple Silverlight control that contains two buttons, a text box to capture user input, and a text block to display the content returned from the Web service. The first example demonstrates how to make a request using WebClient, the second demonstrates the same request using HttpWebRequest. Both requests are asynchronous.

First, I show you the simple UI. It’s some stack panels, two buttons, a text box that accepts user and a text block to display the output from the Web service.

<StackPanel Background="White">

    <StackPanel Orientation="Horizontal">

        <Button Width="250" Content="Click for request with

          HttpWebRequest" Click="Button1_Click"  />

        <Button Width="250" Content="Click for request with WebClient"

            Click="Button2_Click" />

    </StackPanel>

    <StackPanel Orientation="Horizontal">

    <TextBlock  Text="Enter a number between 1-5: " />

    <TextBox  Text="1" x:Name="numTextBox" Width="20" />

    </StackPanel>

    <TextBlock x:Name="resultBlock" />

</StackPanel>

The request will go to a Digg Web service that returns the last photos uploaded to its gallery service. This service that allows you to use the URL to specify the expected response type and the number of photos to return, which I will do. In addition, I must specify an AppKey, which is required by the Digg Web service. It’s important to notice that Digg has the required cross domain policy in place to allow calls from my Silverlight application.

First I declare the base URL used by both WebClient and HttpWebRequest:

string baseUri = https://services.digg.com/galleryphotos?count;

 

I’ll use the same URL with both WebClient and HttpWebRequest, but since I'll append the number of photos to return, I’ll build the complete URL for each request using the specified number and the AppKey. In addition, I'll specify an xml response by appending &type=xml to the end of the URL.

To call the service by using WebClient, declare a WebClient object, and in the Page constructor associate its DownloadStringCompleted event with a handler.

WebClient client = new WebClient();

 

client.DownloadStringCompleted +=

   new DownloadStringCompletedEventHandler(

    client_DownloadStringCompleted);

In Button1_Click, I call DownloadStringAsync, passing the complete URL that includes the number specified by the user.

private void Button1_Click(object sender, RoutedEventArgs e)

{

    client.DownloadStringAsync

      (new Uri(baseUri + numTextBox.Text +

      "&appkey=http%3A%2F%2Fsilverlight.net&type=xml"));

}

In the DownloadStringCompleted event-handler, I check that the Error property of the event args is null, and either output the response or the error message to the text block.

void client_DownloadStringCompleted(object sender,

  DownloadStringCompletedEventArgs e)

{

    if (e.Error == null)

  resultBlock.Text = "Using WebClient: "+ e.Result;

  else

  resultBlock.Text = e.Error.Message;

}

 

Next, I’ll made the same call using HttpWebRequest. In Button2_Click, I create the HttpWebRequest by calling HttpWebRequest.Create, passing the URL built from the baseUrl, the user-specified photo count, and AppKey. I call BeginGetResponse on the request, passing the callback method as a new AsyncCallback object and the request object as the state parameter. I’ll use the request object in the callback to retrieve the response.

private void Button2_Click(object sender, RoutedEventArgs e)

{

    HttpWebRequest request =

      (HttpWebRequest)HttpWebRequest.Create(new Uri(baseUri +

  numTextBox.Text + "&appkey=http%3A%2F%2Fsilverlight.net&type=xml"));

  request.BeginGetResponse(new AsyncCallback(ReadCallback),

       request);

}

In the callback method, ReadCallback, I retrieve the request with the AsyncState property of the asynchronousResult parameter, and get the response by calling EndGetResponse on the request. Finally I use a StreamReader to read the results and output them to the TextBlock.

private void ReadCallback(IAsyncResult asynchronousResult)

{

    HttpWebRequest request =

      (HttpWebRequest)asynchronousResult.AsyncState;

    HttpWebResponse response =

      (HttpWebResponse)request.EndGetResponse(asynchronousResult);

   using (StreamReader streamReader1 =

      new StreamReader(response.GetResponseStream()))

      {

      string resultString = streamReader1.ReadToEnd();

      resultBlock.Text = "Using HttpWebRequest: " + resultString;

      }

}

The results are essentially the same either way, but for a more complex request, if I need to specify headers, content type or need more control over my request, I’ll need to use HttpWebRequest.

Hopefully this helps you get started with your own Web service calls. If you need more help, see my previous post, which also points to two other great blog posts on the topic.

--Cheryl

Comments

  • Anonymous
    April 01, 2008
    PingBack from http://blogs.msdn.com/silverlight_sdk/archive/2008/04/01/using-webclient-and-httpwebrequest.aspx

  • Anonymous
    May 19, 2009
    This is a very helpful post.  So, thank you. I'm having a bit of trouble in the callback for the httpwebrequest.  Basically, accessing the "Text" property of the TextBlock throws a System.UnauthorizedAccessException error.  I've really not modified what you've got here.  Any thought on what I might be doing wrong? Thanks.

  • Anonymous
    May 19, 2009
    OK ... you can disregard my question.  I see that I need to use Dispatcher.BeginInvoke to interact with the UI thread.

  • Anonymous
    July 28, 2011
    How to read service description of the service?

  • Anonymous
    September 20, 2011
    Hi. I have problems using WebClient  to retrieve a simple text from a web service using Internet Explorer 8. I took Fiddler as an HTTP packet sniffer and I discovered that only on IE the request is not made to that service. I used "OpenReadAsync" method to continously get data from the service, but it never works with IE. I have tried with Chrome and FF and everything works fine. Data is coming every couple of seconds and I can see the packets sent in Fiddler. Do you know what is happenning behind the scenes with IE and my WebClient functionality ?  Thanks in advance.

  • Anonymous
    October 25, 2011
    Maybe IE has a proxy setting/configuration it's using. Could check the LAN setting in IE to confirm.

  • Anonymous
    November 26, 2013
    This is a very helpful post.  So, thank you.

  • Anonymous
    February 06, 2014
    Can we use the WebClient in Windows phone 8??