Tuesday, May 24, 2011

ASP.NET: Extending the WebClient Class

System.Net.WebClient is a convenience "wrapper" class around WebRequest and WebResponse that greatly simplifies the basic HTTP operations of GET and POST. However, as a wrapper, it does not expose the underlying details of the Request and Response, which can cause some frustration as developers begin to realize they may need to use HttpWebrequest and HttpWebResponse and write a lot more code than they wanted to.

However, you can gain access to the underlying details by subclassing WebClient. This allows you to override GetWebResponse, GetWebRequest, handle cookies, and to get a final url where autoredirection lands the WebClient on a different target page than it originally requested, along with other features.  Decompiled, the WebClient class consists of 3,237 lines of very complex and carefully engineered code. Most of this is hidden from the user.

This is a sample WebClientEx class derived from WebClient that implements most of the extra features developers need.

The easiest way to explain this is to have a look at the code for the class, as the comments tell all:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Net;
namespace WebUtil
{
    /// <summary>
    /// A class to extend WebClient with additional features
    /// </summary>
    public class WebClientEx : WebClient
    {
         private CookieContainer _cookieContainer;
         private string _userAgent;
        private int _timeout;
    Uri _responseUri;
        /// <summary>
        /// Gets or sets the timeout.
        /// </summary>
        /// <value>
        /// The timeout.
        /// </value>
        public int Timeout
        {
            get { return _timeout; }
            set { _timeout = value; }
        } 
        public WebClientEx()
        {
             this._cookieContainer = new CookieContainer();
             this.SetTimeout(60 * 1000);
        }
        /// <summary>
        /// Gets or sets custom user agent.
        /// </summary>
        /// <value>
        /// The user agent.
        /// </value>
        public string UserAgent
        {
            get { return _userAgent; }
            set { _userAgent = value; }
             
        }

Read more: EggCafe