WebRequest and WebResponse Classes

 
Chapter 20 - Accessing the Internet
bySimon Robinsonet al.
Wrox Press 2002
  

Although the WebClient class is very simple to use, it has very limited features. In particular, you cannot use it to supply authentication credentials a particular problem with uploading data is that not many sites will accept uploaded files without authentication! It is possible to add header information to requests and to examine any headers in the response, but only in a very generic sense there is no specific support for any one protocol. This is because WebClient is a very general-purpose class designed to work with any protocol for sending a requests and receiving a response (such as HTTP, or FTP). It cannot handle any features specific to any one protocol, such as cookies, which are specific to HTTP. If you want to take advantage of these features you need to use a family of classes based on two other classes in the System.Net namespace: WebRequest and WebResponse .

We will start off by showing you how to download a web page using these classes this is the same example as before, but using WebRequest and WebResponse . In the process we will uncover the class hierarchy involved, and then see how to take advantage of extra HTTP features supported by this hierarchy.

The following code shows the modifications we need to make the BasicWebClient sample use the WebRequest and WebResponse classes.

 public Form1() {    InitializeComponent();   WebRequest wrq = WebRequest.Create("http://www.wrox.com");     WebResponse wrs = wrq.GetResponse();     Stream strm = wrs.GetResponseStream();   StreamReader sr = new StreamReader(strm);     string line;    while ((line = sr.ReadLine()) != null)    {       listBox1.Items.Add(line);    }    strm.Close(); } 

In the code we start by instantiating an object representing a web request. We don't do this using a constructor, but instead call the static method WebRequest.Create() . As we will explain in more detail later, the WebRequest class is part of a hierarchy of classes supporting different network protocols. In order to receive a reference to the correct object for the request type, a factory mechanism is in place. The WebRequest.Create() method will create the appropriate object for the given protocol.

The WebRequest class represents the request for information to send to a particular URI. The URI is passed as a parameter to the Create() method. A WebResponse represents the data we retrieve from the server. By calling the WebRequest.GetResponse() method, we actually send the request to the web server and create a WebResponse object to examine the return data. As with the WebClient object, we can obtain a stream to represent the data, but, in this case we use the WebResponse.GetResponseStream() method.

Other WebRequest and WebResponse Features

We will quickly mention a couple of the other areas supported by WebRequest , WebResponse , and other related classes.

HTTP Header Information

An important part of the HTTP protocol is the ability to send extensive header information with both request and response streams. This information can include cookies, and the details of the particular browser sending the request (the user agent). As you would expect, the .NET Framework provides full support for accessing the most significant data. The WebRequest and WebResponse classes provide some support for reading the header,information. However, two derived classes provide additional HTTP-specific information: HttpWebRequest and HttpWebResponse . As we will explain in more detail later, creating a WebRequest with an HTTP URI results in an HttpWebRequest object instance. Since HttpWebRequest is derived from WebRequest , you can use the new instance anywhere a WebRequest is required. In addition, you can cast the instance to an HttpWebRequest reference and access properties specific to the HTTP protocol. Likewise, the GetResponse() method call will actually return an HttpWebResponse instance as a WebResponse reference when dealing with HTTP. Again, you can perform a simple cast to access the HTTP-specific features.

We can examine a couple of the header properties by adding the following code before the GetResponse() method call.

   WebRequest wrq = WebRequest.Create("http://www.wrox.com");     HttpWebRequest hwrq = (HttpWebRequest)wrq;     listBox1.Items.Add("Request Timeout (ms) = " + wrq.Timeout);     listBox1.Items.Add("Request Keep Alive = " + hwrq.KeepAlive);     listBox1.Items.Add("Request AllowAutoRedirect = " + hwrq.AllowAutoRedirect);   

The Timeout property is specified in milliseconds , and the default value is 100,000. You can set the timeout property to control how long the WebRequest object will wait on the response before throwing a WebException . You can check the WebException.Status property to see the reason for an exception. This enumeration includes status codes for timeouts, connection failures, protocol errors, and more.

The KeepAlive property is a specific extension to the HTTP protocol, so we access this property through an HttpWebRequest reference. KeepAlive allows multiple requests to use the same connection, saving time in closing and reopening connections on subsequent requests. The default value for this property is true .

The AllowAutoRedirect property is also specific to the HttpWebRequest class. Use this property to control if the web request should automatically follow redirection responses from the web server. Again, the default value is true . If you want to allow only a limited number of redirections, set the MaximumAutomaticRedirections property of the HttpWebRequest to the desired number.

While the request and response classes expose most of the important headers as properties, you can also use the Headers property itself to view the entire collection of headers. Add the following code after the GetResponse() method call to place all of the headers in the listbox control:

   WebRequest wrq = WebRequest.Create("http://www.wrox.com");     WebResponse wrs = wrq.GetResponse();     WebHeaderCollection whc = wrs.Headers;     for(int i = 0; i < whc.Count; i++)     {     listBox1.Items.Add("Header " + whc.GetKey(i) + " : " + whc[i]);     }   

This example code produces the following list of headers:

click to expand

Authentication

A further property in the WebRequest class is the Credentials property. If we needed authentication credentials to accompany our request, we could create an instance of the NetworkCredential class (also from the System.Net namespace) with a username and password. You could place the following code before the call to GetResponse() .

   NetworkCredential myCred = new NetworkCredential("myusername", "mypassword");     wrq.Credentials = myCred;   

Asynchronous Page Requests

An additional feature of the WebRequest class is the ability to request pages asynchronously. This feature is significant since there can be quite a long delay between sending a request off to a host and receiving the response. Methods such as WebClient.DownloadData() and WebRequest.GetResponse() will not return until the response from the server is complete. You might not want your application frozen due to a long period of inactivity, and in such scenarios it is better to use the BeginGetResponse() and EndGetResponse() methods. BeginGetResponse() works asynchronously and returns almost immediately. Under the covers, the runtime will asynchronously manage a background thread to retrieve the response from the server. Instead of returning a WebResponse object, BeginGetResponse() returns an object implementing the IAsyncResult interface. With this interface you can poll or wait for the response to become available, and then invoke EndGetResponse() to gather the results.

You can also pass a callback delegate into the BeginGetResponse() method. The target of a callback delegate is a method returning void and accepting an IAsyncResult reference as a parameter. When the worker thread is finished gathering the response, the runtime invokes the callback delegate to inform you of the completed work. As shown in the following code, calling EndGetResponse() in the callback method allows you to retrieve the WebResponse object.

   public Form1()     {     InitializeComponent();     WebRequest wrq = WebRequest.Create("http://www.wrox.com");     wrq.BeginGetResponse(new AsyncCallback(OnResponse), wrq);     }     protected void OnResponse(IAsyncResult ar)     {     WebRequest wrq = (WebRequest)ar.AsyncState;     WebResponse wrs = wrq.EndGetResponse(ar);     // read the response ...     }   

Notice how you can retrieve the original WebRequest object by passing the object as the third parameter to BeginGetResponse() . The third parameter is an object reference known as the state parameter. During the callback method you can retrieve the same state object using the AsyncState property of IAsyncResult .

  


Professional C#. 2nd Edition
Performance Consulting: A Practical Guide for HR and Learning Professionals
ISBN: 1576754359
EAN: 2147483647
Year: 2002
Pages: 244

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net