In order to use multiple proxy servers, you need to create the BrowserContext instance for each proxy. This article demonstrates how to implement the WinForms application which loads the specified web page using the different proxies.


In the sample application, the main form contains the address text box, the navigation button, and the tab control. The tab control contains the tab for direct loading (without using the proxy server) and a tab demonstrating the usage of each proxy server from the list of specified proxies.


The configuration of the proxy server is defined using the ProxyConfig class:


public class ProxyConfig
{
    public string IpAddress { get; }
    public int Port { get; }

    public bool IsAuthRequired { get; }

    public string Username { get; }
    public string Password { get; }

    public ProxyConfig(string ipAddress, int port, bool isAuthRequired = false, string username = "", string password = "")
    {
        IpAddress = ipAddress;
        Port = port;
        IsAuthRequired = isAuthRequired;
        Username = username;
        Password = password;
    }

    public override string ToString()
    {
        return string.Format("{0}:{1}", IpAddress, Port);
    }
}


If the proxy requires authentication then such authentication should be performed by the network delegate. The ProxyNetworkDelegate class implements such authentication:


public class ProxyNetworkDelegate : DefaultNetworkDelegate
{
    private string user;
    private string password;

    public ProxyNetworkDelegate(string user, string password)
    {
        this.user = user;
        this.password = password;
    }

    public override bool OnAuthRequired(AuthRequiredParams parameters)
    {
        if (parameters.IsProxy)
        {
            parameters.Username = user;
            parameters.Password = password;
        }

        return false;
    }
}


Each tab page accepts the proxy configuration (the ProxyConfig class instance) and should create the BrowserContext instance according to this configuration. After that, the Browser instance and the BrowserView instance should be created based on the created context:


public class ProxyTabPage : TabPage
{
    private ProxyConfig proxyConfig;
    private string contextDirectory;

    private BrowserContext context;
    private Browser browser;
    private WinFormsBrowserView browserView;

    public ProxyTabPage(ProxyConfig proxyConfig)
    {
        this.proxyConfig = proxyConfig;

        //Generate unique context directory name
        contextDirectory = Guid.NewGuid().ToString("N");

        Text = proxyConfig != null ? proxyConfig.ToString() : "Direct access";

        InitializeBrowser();
    }

    public void GoToUrl(string url)
    {
        browser.LoadURL(url);
    }

    private void InitializeBrowser()
    {
        BrowserContextParams contextParams = new BrowserContextParams(contextDirectory);
        //The BrowserContext should be stored in RAM
        contextParams.StorageType = StorageType.MEMORY;

        //For non-default proxy settings
        if (proxyConfig != null)
        {
            //Setup the proxy rules
            contextParams.ProxyConfig =
                new CustomProxyConfig(string.Format("http={0};https={0};socks={0}", proxyConfig.ToString()));
        }

        context = new BrowserContext(contextParams);

        //Check if the proxy server requires authentication
        if (proxyConfig != null && proxyConfig.IsAuthRequired)
        {
            //Create the network delegate and assign it to the context
            context.NetworkService.NetworkDelegate =
                new ProxyNetworkDelegate(proxyConfig.Username, proxyConfig.Password);
        }

        browser = BrowserFactory.Create(context);
        browserView = new WinFormsBrowserView(browser) {Dock = DockStyle.Fill};
        Controls.Add(browserView);
    }

    public void DisposeBrowser()
    {
        browserView.Dispose();
        browser.Dispose();
        context.Dispose();
    }
}


The tab control accepts the list of the proxy server configurations and creates the tab for each proxy and for the direct access:


public class ProxyTabControl : TabControl
{
    public List<ProxyConfig> ProxyConfigs { get; }

    public ProxyTabControl(List<ProxyConfig> proxyConfigs)
    {
        ProxyConfigs = proxyConfigs;

        CreateProxyTabs();
    }

    public void GoToUrl(string url)
    {
        foreach (TabPage tabPage in TabPages)
        {
            ProxyTabPage proxyTabPage = tabPage as ProxyTabPage;
            if (proxyTabPage != null)
            {
                proxyTabPage.GoToUrl(url);
            }
        }
    }

    private void CreateProxyTabs()
    {
        //Create the tab bor the direct access
        ProxyTabPage tabWithoutProxy = new ProxyTabPage(null);
        TabPages.Add(tabWithoutProxy);
        
        //Create the tab for the access via proxy
        foreach (ProxyConfig proxyConfig in ProxyConfigs)
        {
            ProxyTabPage tabWithProxy = new ProxyTabPage(proxyConfig);
            TabPages.Add(tabWithProxy);
        }
    }

    public void DisposeTabs()
    {
        foreach (TabPage tabPage in TabPages)
        {
            ProxyTabPage proxyTabPage = tabPage as ProxyTabPage;
            if (proxyTabPage != null)
            {
                proxyTabPage.DisposeBrowser();
            }
        }
    }
}


In the MainForm constructor the ProxyTabControl is created using the defined proxy list:


public partial class MainForm : Form
{
    private ProxyTabControl tabControl;

    public MainForm()
    {
        InitializeComponent();

        tabControl = new ProxyTabControl(new List<ProxyConfig>()
        {
            new ProxyConfig("23.111.166.114", 8080),
            new ProxyConfig("52.224.181.154", 3128)
        })
        { Dock = DockStyle.Fill };

        BrowserTabPanel.Controls.Add(tabControl);

        AddressTextBox.Text = "whatismyproxy.com";
        tabControl.GoToUrl(AddressTextBox.Text);

        Closed += MainForm_Closed;
    }

    private void MainForm_Closed(object sender, EventArgs e)
    {
        tabControl.DisposeTabs();
    }

    private void GoButton_Click(object sender, EventArgs e)
    {
        tabControl.GoToUrl(AddressTextBox.Text);
    }
}