How to Use a Partial Class and Alternative HTTP Authentication Methods using GetWebReques

Today, I was talking with a friend about a problem he was having using a third party web service from within a .NET application he had written. Apparently, there was an authentication problem, even though it was verified that the NetworkCredential object was instantiated correctly and according to the third party’s spec in how to authenticate – using Basic Authentication.

It turned out that the third party hosted web service’s web server was expecting to see the credentials pass on the first request, which the default implementation in ASP.NET does not support, per section 2 of the spec found in RFC 2617.

The work around, per a newsgroup post, involves overriding GetWebRequest in the web service proxy class that is generated when adding the Web Reference. Since this was in 2.0, we were able to take advantage of the partial class feature so that the generated code won’t have to be modified thus preserving the changes between Web Reference updates.

To create the partial class we need to get the class name and class derivation, as well as the namespace, of the generated proxy class. So the first thing we need to do is find the generated source.

At first glance, it is no where to be found, but if you jump over to the Class View, instead of the Solution View, you can find the name space and dig down into the namespace for the Web Service and locate the class that represents the generated proxy class.

Simply right click on this class and select “Show Definition”, which will open up the code for you to see the namespace, class and derivation lines.

Copy and paste these two lines into a new “.cs” file and define the single override in the snippet below.

protected override System.Net.WebRequest GetWebRequest(Uri uri) { System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)base.GetWebRequest(uri); if (this.PreAuthenticate) { System.Net.NetworkCredential nc = this.Credentials.GetCredential(uri, "Basic"); if (nc != null) { byte[] credBuf = new System.Text.UTF8Encoding().GetBytes(nc.UserName + ":" + nc.Password); request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credBuf); } } return request; }

That’s all there is to it.