I'm using C# and .NET 3.5. As you know, we can add custom header to Navigate()
on the web browser control like this:
var myUrl = "http://example.com/mypage.htm";
System.Uri uri = new Uri(myUrl);
byte[] authData = System.Text.UnicodeEncoding.UTF8.GetBytes("user:password");
string authHeader =
"Authorization: Basic " + Convert.ToBase64String(authData) + "\r\n" +
"User-Agent: MyUserAgent\r\n";
webTDW8961nd.Navigate(uri, "", null, authHeader);
In the example above we set a Basic Authorization header for a single navigation.
Now let talk about redirection. If we want to execute javascript which will redirect to another page, the Basic Authorization header won't be included.
What is your solution? How can I add a header which works for all of the requests and not only once?
The problem is that while both WinForm's and WPF's
WebBrowser
are nothing else but a relatively thin wrapper around the ActiveX IE control, they don't expose all the events of interest to us (and the second provides even less than the first). There are two ways to solve this: first, to subclass the WF browser control and add what you need or to use the WPF one and add the hooks there. I found the second approach to be more convenient in a WPF application.You only need the relevant interfaces. The easiest way is to add a reference to Microsoft Internet Controls (you'll find this under the COM heading is VS). This opens up a namespace called
SHDocVw
that contains all we need (if, for any reason, you want to get rid of this dependency, you can simply copy the P/Invoke interfaces used into your own code).You can get the underlying browser using reflection. It will return
null
if you call it too early, so I put it into theWebBrowser.Navigating
handler:As soon as you have it, you can do nice things with the browser. For instance, you can use various properties and methods not exposed directly:
and add the missing event hooks:
There are two event interfaces, the
2
variant contains the newer events. You can look all this up on MSDN.And, back to the headers: the
BeforeNavigate2
event allows you to put your extra headers into the provided object:To add custom header for each request you can implement extension method:
And then call it instead of standard method:
The second question is about redirecting. But your scenario will not work in a simple browser and fiddler. It is the feature of web protocol, when you redirect to another Uri you initiate new request with new properties. You can compose your request in js code.
When handling
BeforeNavigate2
if you want to include additional headers, you need to cancel the current navigating event, you also need to stop the browser. Then you need to navigate again to the URL passing additional headers.Here is the way that I handled the basic authentication which can be tested by
guest
as username and password for this url: https://jigsaw.w3.org/HTTP/Basic/Note - Navigating will not raise on Refresh
There is a feature/flaw in browser with refresh. When you refresh the browser,
Navigating
event will not raise, which means the header will not be added in case of refresh. A workaround for that is disabling shortcut and context menu: