Your PC can't even




C# - Cookie Aware Web Client

This post documents how to extend the baseline WebClient in order to have it preserve cookies sent using the Set-Cookie header for subsequent calls.

Why? How is this useful?

  • I’ve had to interface/write a few APIs that must have an endpoint that initiates a session via a Set-Cookie header. In these instances, having a cookie aware webclient takes care of the dirty work for tracking these cookies.

  • I’ve also had instances where I needed to perform screen scraping to emulate an action programmatically that is only present in the UI. For these scenarios, a cookie aware webclient tends to be necessary to preserve state between the multiple calls we are emulating from the UI.

Implementing the class

		
public class CookieAwareWebClient : System.Net.WebClient
{
        private System.Net.CookieContainer Cookies = new System.Net.CookieContainer();

        protected override System.Net.WebRequest GetWebRequest(Uri address)
	{
	System.Net.WebRequest request = base.GetWebRequest(address);
        if (request is System.Net.HttpWebRequest)
	{
        var hwr = request as System.Net.HttpWebRequest;
        //By Reference, as hwr.CookieContainer gets updated so does Cookies.
        //We then assign the collection back to the collection at the start of the call
		hwr.CookieContainer = Cookies;
	}
        return request;
	}
}
		
		
Usage.
Calling an API endpoint to initiate a cookie based session.
			
using (var Client = new CookieAwareWebClient())
{
        string SiteBase = "https://somewebapi.domain.net";
        string content = "application/x-www-form-urlencoded";
	Client.Headers.Add("Content-Type", content);
        string ApiKey = @"_apikey=SomeApiKey";
        //Call into an API that has a CookieSession endpoint
        string response = Encoding.UTF8.GetString(Client.UploadData(string.Format("{0}/Authentication/CookieSession", SiteBase), Encoding.UTF8.GetBytes(ApiKey)));
	
        //Use our cookie to verify authentication
        string resp2 = Encoding.UTF8.GetString(Client.DownloadData(string.Format("{0}/Authentication/VerifyAuth", SiteBase)));
}