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:

C#

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);
    }
}

VB.NET

Public Class ProxyConfig
    Public ReadOnly Property IpAddress As String
    Public ReadOnly Property Port As Integer
    Public ReadOnly Property IsAuthRequired As Boolean
    Public ReadOnly Property Username As String
    Public ReadOnly Property Password As String

    Public Sub New(ipAddress As String, port As Integer, Optional isAuthRequired As Boolean = False,
                   Optional username As String = "", Optional password As String = "")
        IpAddress = ipAddress
        Port = port
        IsAuthRequired = isAuthRequired
        Username = username
        Password = password
    End Sub

    Public Overrides Function ToString() As String
        Return String.Format("{0}:{1}", IpAddress, Port)
    End Function
End Class


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

C#

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;
    }
}

VB.NET

Public Class ProxyNetworkDelegate
    Inherits DefaultNetworkDelegate

    Private user As String
    Private password As String

    Public Sub New(ByVal user As String, ByVal password As String)
        Me.user = user
        Me.password = password
    End Sub

    Public Overrides Function OnAuthRequired(ByVal parameters As AuthRequiredParams) As Boolean
        If parameters.IsProxy Then
            parameters.Username = user
            parameters.Password = password
        End If

        Return False
    End Function
End Class


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:

C#

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();
    }
}

VB.NET

Public Class ProxyTabPage
    Inherits TabPage

    Private proxyConfig As ProxyConfig
    Private contextDirectory As String
    Private context As BrowserContext
    Private browser As Browser
    Private browserView As WinFormsBrowserView

    Public Sub New(ByVal proxyConfig As ProxyConfig)
        Me.proxyConfig = proxyConfig
        contextDirectory = Guid.NewGuid().ToString("N")
        Text = If(proxyConfig IsNot Nothing, proxyConfig.ToString(), "Direct access")
        InitializeBrowser()
    End Sub

    Public Sub GoToUrl(ByVal url As String)
        browser.LoadURL(url)
    End Sub

    Private Sub InitializeBrowser()
        Dim contextParams As BrowserContextParams = New BrowserContextParams(contextDirectory)
        contextParams.StorageType = StorageType.MEMORY

        If proxyConfig IsNot Nothing Then
            contextParams.ProxyConfig = New CustomProxyConfig(String.Format("http={0};https={0};socks={0}", proxyConfig.ToString()))
        End If

        context = New BrowserContext(contextParams)

        If proxyConfig IsNot Nothing AndAlso proxyConfig.IsAuthRequired Then
            context.NetworkService.NetworkDelegate = New ProxyNetworkDelegate(proxyConfig.Username, proxyConfig.Password)
        End If

        browser = BrowserFactory.Create(context)
        browserView = New WinFormsBrowserView(browser) With {
            .Dock = DockStyle.Fill
            }
        Controls.Add(browserView)
    End Sub

    Public Sub DisposeBrowser()
        browserView.Dispose()
        browser.Dispose()
        context.Dispose()
    End Sub
End Class


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

C#

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();
            }
        }
    }
}

VB.NET

Public Class ProxyTabControl
    Inherits TabControl

    Public ReadOnly Property ProxyConfigs As List(Of ProxyConfig)

    Public Sub New(ByVal proxyConfigs As List(Of ProxyConfig))
        ProxyConfigs = proxyConfigs
        CreateProxyTabs()
    End Sub

    Public Sub GoToUrl(ByVal url As String)
        For Each tabPage As TabPage In TabPages
            Dim proxyTabPage As ProxyTabPage = TryCast(tabPage, ProxyTabPage)

            If proxyTabPage IsNot Nothing Then
                proxyTabPage.GoToUrl(url)
            End If
        Next
    End Sub

    Private Sub CreateProxyTabs()
        Dim tabWithoutProxy As ProxyTabPage = New ProxyTabPage(Nothing)
        TabPages.Add(tabWithoutProxy)

        For Each proxyConfig As ProxyConfig In ProxyConfigs
            Dim tabWithProxy As ProxyTabPage = New ProxyTabPage(proxyConfig)
            TabPages.Add(tabWithProxy)
        Next
    End Sub

    Public Sub DisposeTabs()
        For Each tabPage As TabPage In TabPages
            Dim proxyTabPage As ProxyTabPage = TryCast(tabPage, ProxyTabPage)

            If proxyTabPage IsNot Nothing Then
                proxyTabPage.DisposeBrowser()
            End If
        Next
    End Sub
End Class


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

C#

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);
    }
}

VB.NET

Public Partial Class MainForm
    Inherits Form

    Private tabControl As ProxyTabControl

    Public Sub New()
        InitializeComponent()
        tabControl = New ProxyTabControl(New List(Of ProxyConfig)() From {
                                            New ProxyConfig("23.111.166.114", 8080),
                                            New ProxyConfig("52.224.181.154", 3128)
                                            }) With {
                                                .Dock = DockStyle.Fill
                                                }
        BrowserTabPanel.Controls.Add(tabControl)
        AddressTextBox.Text = "whatismyproxy.com"
        tabControl.GoToUrl(AddressTextBox.Text)
        Closed += AddressOf MainForm_Closed
    End Sub

    Private Sub MainForm_Closed(ByVal sender As Object, ByVal e As EventArgs)
        tabControl.DisposeTabs()
    End Sub

    Private Sub GoButton_Click(ByVal sender As Object, ByVal e As EventArgs)
        tabControl.GoToUrl(AddressTextBox.Text)
    End Sub
End Class