Web Services and Proxy Servers

I'm currenting working with a team that is putting the finishing touches on a commercial application that uses web services as a major component of the infrastructure.  As part of putting the client portion through its paces, an environment that included a proxy server was tested.  The initial result was not surprising to anyone who has significant experience with web services:  a connection could not be made exception was thrown. The reason for this problem is that the method for defining a proxy server to the web service proxy class on the client side is a little unexpected.  And I apologize in advance for having to use the same word (proxy) to describe to separate items (the server and the web service class). 

If you are running Internet Explorer, then the place where the the proxy server settings are configured is in the Tools | Internet Options dialog.  Within the dialog, click on the Connections tab and the LAN Settings button.  Here you can specify whether proxy server settings are required and which server and port are used.  You can also identify whether local addresses are exempt from the proxy process.  This is fairly well known information, especially if you normally operate from behind a proxy server.

The disconnect occurs when you make calls to web services from this same machine.  Under the covers, the HttpWebRequest class is used to transmit the call to the desired server.  However, even when the proxy server information has been specified as just described, those details are NOT used by HttpWebRequest.  Instead, by default, no proxy is used to handle the request.  This is what causes the connection exception. I know the first time I ran into this issue was a surprise to me.

There are two possible solutions to this problem.  The first is to assign a WebProxy object to the Proxy property on the web service proxy class.  You can programmatically specify the proxy server information, but that is very difficult to modify.  Instead of creating the WebProxy object on the fly, use the GetDefaultProxy static method on the System.Net.WebProxy object.  This method reads “the nondynamic proxy settings stored by Internet Explorer 5.5” and returns them as a WebProxy object that can be assigned to the Proxy property .  This technique works fine assuming that your client has IE installed and that none of the scripts run at login time have modified the proxy settings.

There is an alternative that is a little more flexible.  There is a app.config element called defaultProxy that is part of the System.Net configuration section.  Within this element, the details of the proxy server can be specified independently of the IE settings.  The basic format of the defaultProxy element can be seen below.

<system.net>
   <defaultProxy>
      <proxy
         proxyaddress = "http://proxyserver:80"
         bypassonlocal = "true"
      />
   </defaultProxy>
</system.net>

The proxy element also includes an attribute called usesystemdefault which, when set to true, causes the IE settings to be used.  The benefit of this approach is that no additional coding is required.  The settings defined in defaultProxy are use by HttpWebRequest (and, therefore, web service calls) with no change to the application required.

As an added benefit, this element can be added to machine.config, which allows it to be applied to every HttpWebRequest made from the client machine regardless of the application.  Keeping in mind that an uneducated developer could assign the Proxy object in code, overriding this nice, easily configurable default.