1

I have an application which was using a System.Windows.Forms.WebBrowser to enable users to navigate to a web page in order to allow an OAuth2 autentication to take place. This works for one authentication but for another it seems that WebBrowser isn't modern enough, so I'm attempting to replace WebBrowser with a ChromiumWebBrowser from CefSharp.

This is more or less working in that I can see the string I require in a property called :

e.Browser.FocusedFrame.Browser.Url

See the attached screen shotsApp in debug mode.App in debug mode. of my app running in debug mode.

I just need to be able to parse the string that I can see is there looking for "code=" then extract the string between "code=" and "&country=". In the screen shot I need the "GB%2F68f9239a-80a5-4c66-bc2e-f40ec3fd35e9", which is the authorisation code, to exchange for a token and refresh token.

How do I get access this property?

Thanks in advance. Jim.

I've got an "EventArgs e" which appears to contain the url string containing the code I require and I'm hoping to be able to say something like :

string url = e.Browser.FocusedFrame.Browser.Url;

Then I'll be able get a list of the the parameters and if one of the parameters begins with "code=" I'll have my code for the exchange and that's job done.

The previous code produces a "WebBrowserNavigatedEventArgs e" and the app is able to parse "e.Url.Query". See the attached screen shot EventArgs03.png.Old WebBrowser with parseable url

I just want to do something similar.

Regards, Jim.

  • 1
    We can't tell how you're subscribing to the event, or what the declaration looks like. (I can't see a Navigated event declaration in ChromiumWebBrowser or its interfaces.) – Jon Skeet Jul 17 '23 at 10:18
  • Unrelated, but may come back and boomerang you in the head: If this is commercial code and you have customers that exclude certain browsers/engines from being used in their network, you may want to be ready for that. (Don't know if this is specifically notorious to the country I am in, though) – Fildor Jul 17 '23 at 10:29
  • Hi Jon, The event is : this._chromiumBrowser.LoadingStateChanged += OnLoadingStateChanged; which fires when a new web page is loaded. Which fires OnLoadingStateChanged. The Navigated references come from the original WebBrowser and I shouldn't have used them my apologies. The thing is the event has fired and I've got the EventArgs (e) which has the string I require. – Jim Borland Jul 17 '23 at 11:07
  • I've got it working I will post the solution when I've done a bit more testing. – Jim Borland Jul 17 '23 at 12:01
  • I just had to add the following : LoadingStateChangedEventArgs args = (LoadingStateChangedEventArgs)e; Which gave me access to the properties of the EventArgs. So I was able to parse args.Browser.Focused.Url which is the property I could see in debug mode which held the string I needed. Thanks for all your input, it's much appreciated. – Jim Borland Jul 17 '23 at 12:46
  • @Fildor, Are you suggesting that I should build some code that capable of using other web browers? Do you come accross this regularly and what browser do you use to get around it? – Jim Borland Jul 17 '23 at 13:03
  • I am not suggesting anything. I have had the issue that customer's IT departments only "certified" a specific browser and even only a range of versions of that. And this was enforced company wide. We needed to make minor changes to our UI to be compliant. But if there is a browser baked in to your software, then that may cause trouble. But this kind of policy may also die out. Or it's practically never going to happen in your industry. – Fildor Jul 17 '23 at 14:06
  • Tl;dr: I am **not** suggesting that's something you need to act upon immediately. Just a little heads up, that this _could_ be a thing. Just so you have heard of that. – Fildor Jul 17 '23 at 14:08
  • @Fildor what would the alternative be to baking in a browser which is capable of handling modern web pages? Is there a generic but modern browser I could use or is a case of trying to use a browser which is completely outside my software? My impression that I'm required to add a browser to my app! – Jim Borland Jul 18 '23 at 14:18
  • Cannot tell, I am afraid. We were able to adjust quite easily, because we only had to make our html/js output compatible with the browser and version range of said company. So, the browser wasn't technically _part of_ our application, like it is in your case. – Fildor Jul 18 '23 at 14:46

2 Answers2

0

The standard and recommended approach is to define your event handler with a matching method signature.

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-subscribe-to-and-unsubscribe-from-events#to-subscribe-to-events-programmatically

_chromiumBrowser.LoadingStateChanged += OnLoadingStateChanged;

// Define an event handler method whose signature matches the delegate signature for the event.
private void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
{
    Dictionary<string, string> parameters = null;
    var url = args.Browser.FocusedFrame.Url;
    if(url.Contains("code="))
    {
        int i = url.IndexOf('?');
        string query = url.Substring(i, url.Length - i);
        parameters = ParseFragment(query, new char[] { '&', '?' });
        this._authorizationCode = parameters["code"];
    }
}

There is a working example available at https://github.com/cefsharp/CefSharp.MinimalExample/blob/cefsharp/113/CefSharp.MinimalExample.WinForms/BrowserForm.cs#L94-L100

amaitland
  • 4,073
  • 3
  • 25
  • 63
-1

LoadingStateChangedEventArgsThe event I need to handle was ChroniumBrower.LoadingStateChanged :

this._chromiumBrowser.LoadingStateChanged += OnLoadingStateChanged;

Which fired :

    private void OnLoadingStateChanged(object sender, EventArgs e)
    {
        Dictionary<string, string> parameters = null;
        LoadingStateChangedEventArgs args =  LoadingStateChangedEventArgs)e;
        var url = args.Browser.FocusedFrame.Url;
        if(url.Contains("code="))
        {
            int i = url.IndexOf('?');
            string query = url.Substring(i, url.Length - i);
            parameters = ParseFragment(query, new char[] { '&', '?' });
            this._authorizationCode = parameters["code"];
        }
        

    }

I was struggling to gain access to the required property of e but by adding the line :

LoadingStateChangedEventArgs args = (LoadingStateChangedEventArgs)e;

I was able to parse args.Browser.FocusedFrame.Url which is where the string I need was stored.

Yehor Androsov
  • 4,885
  • 2
  • 23
  • 40
  • You can and should specify the type in our method signature rather than casting. See https://github.com/cefsharp/CefSharp.MinimalExample/blob/cefsharp/113/CefSharp.MinimalExample.WinForms/BrowserForm.cs#L94-L100 – amaitland Jul 20 '23 at 19:09