Wednesday, June 22, 2011

Configuring Proxy settings in .NET config file

Hi all

Usually at work when I wanted to test something that requires to make a call over the web, I had to code two lines into my C# app to allow my application to work over our proxy:


WebRequest.DefaultWebProxy = WebRequest.GetSystemWebProxy();
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultCredentials;


Now, I found that you can actually configure your App.config or Web.config to do this for you.


<configuration>
  <system.net>
    <defaultProxy enabled="true" useDefaultCredentials="true">
    </defaultProxy
>
  </system.net>
</configuration>


This would set the proxy to be used to the one currently configured in Internet Explorer and uses your currently logged in credentials to access the web through the proxy.

If you need to specify a different proxy, you could specify it like this:


<defaultProxy enabled="true">

  <proxy proxyaddress="some new proxy" />
</defaultProxy>


There is just one issue with this, you cannot specify credentials explicitly to use in the configuration file that needs to be used for proxy access. If you have to make use of a proxy and the account you use to log into windows doesn't have access to that proxy, you would have to specify a different set of credentials to be used.
Yes you can code this in C# by specifying Credentials in your Default proxy.
But this is not always desirable.
I did find a post on Stack Overflow where someone suggested that you create a Proxy class and inject it as a Module, which is what I'm going to demonstrate here:

public class MyProxy : IWebProxy
{
    public Uri GetProxy(Uri destination)
    {
        string proxy = ConfigurationManager.AppSettings ["proxyaddress"];
        return new Uri(proxy);
    }

    public bool IsBypassed(Uri host)
    {
        return false;
    }

    public ICredentials Credentials
    {
        get
        {
            string username = ConfigurationManager.AppSettings ["username"];
            string password = ConfigurationManager.AppSettings ["password"];
            return new NetworkCredential(username, password);
        }
        set {  }
    }
}


And in the config file:


<configuration>
    <appSettings>
        <add key="proxyaddress" value="http://proxyaddress"/>
        <add key="username" value="my user"/>
        <add key="password" value="my password"/>
    </appSettings>
    <system.net>
        <defaultProxy enabled="true" useDefaultCredentials="false">
            <module type="MyAssembly.MyProxy,
MyAssembly"/>
        </defaultProxy>
    </system.net>
</configuration> 


This would make use of the proxy we coded to specify which proxy to use and with which credentials. You might want to cache those settings, etc. but this is just a simple example of how to do this. This way you don't have to touch your production code at all and still configure it to be proxy-aware.

I hope this would be useful to some one as it has been for me.

No comments: