Search code examples
c#event-handlingcefsharpchromium-embeddedrequesthandler

Can't achieve RequestHandler to work CefSharp winforms C#


I'm a bit new to c# and CefSharp :-) so be cool with me !

My goal is to call an url, and then explore DOM to retrieve data and then process this data for hypervision purpose. I've achieve that retrieval and my js code work well using EvaluateScriptAsync.

By now i want to track data refresh. The page is updated by a websocket communication, which then update values in the DOM object model.

i think to use RequestHandler and adapt GetResourceResponseFilter; but i can't manage to do that and seems the the methods i've implemented were never called ... i use the Minimal solution dowloaded from cefsharp project site. I just add the two lines at the end of this snippet :

 public BrowserForm()
        {
            InitializeComponent();

            Text = "CefSharp";
            WindowState = FormWindowState.Maximized;

            browser = new ChromiumWebBrowser("www.google.com");
            toolStripContainer.ContentPanel.Controls.Add(browser);

            browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
            browser.LoadingStateChanged += OnLoadingStateChanged;
            browser.ConsoleMessage += OnBrowserConsoleMessage;
            browser.StatusMessage += OnBrowserStatusMessage;
            browser.TitleChanged += OnBrowserTitleChanged;
            browser.AddressChanged += OnBrowserAddressChanged;
            // Add this  for request handler
            Handler.RequestHandler requestHandler = new MyBasicRequestHandler();
            browser.RequestHandler = requestHandler;

And my test handler look like this !

public class MyBasicRequestHandler : CefSharp.Handler.RequestHandler
        {
            public bool OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
            {
                MessageBox.Show ("OnResourceResponse");
                return false;
            }
            public bool OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url)
            {
                MessageBox.Show("OnProtocolExecution : "+url);
                return false;
            }
            public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
            {
                MessageBox.Show("GetResourceResponseFilter : " + request.ReferrerUrl);
                return null;
            }
        }

But nothing is fired !

Any help or advice will be appreciate.

thanks!


Solution

  • Thanks to amaitland kind comments this code works. I've only added few lines to CefSharp.Minimal Example.Winforms solution pulled from github to register the RequestHandler.

    public BrowserForm()
            {
                InitializeComponent();
    
                Text = "CefSharp";
                WindowState = FormWindowState.Maximized;
    
                browser = new ChromiumWebBrowser("https://cefsharp.github.io/");
                toolStripContainer.ContentPanel.Controls.Add(browser);
    
                browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
                browser.LoadingStateChanged += OnLoadingStateChanged;
                browser.ConsoleMessage += OnBrowserConsoleMessage;
                browser.StatusMessage += OnBrowserStatusMessage;
                browser.TitleChanged += OnBrowserTitleChanged;
                browser.AddressChanged += OnBrowserAddressChanged;
                // Add this  for request handler
                Handler.RequestHandler requestHandler = new MyBasicRequestHandler();
                browser.RequestHandler = requestHandler;
    
                var version = string.Format("Chromium: {0}, CEF: {1}, CefSharp: {2}",
                   Cef.ChromiumVersion, Cef.CefVersion, Cef.CefSharpVersion);
    
                var bitness = Environment.Is64BitProcess ? "x64" : "x86";
                var environment = String.Format("Environment: {0}", bitness);
    
                DisplayOutput(string.Format("{0}, {1}", version, environment));
            }
    

    And then I've add code for MyBasicRequestHandler and MyCustomResourceRequestHandler Classes as follow :

    public class MyCustomResourceRequestHandler : CefSharp.Handler.ResourceRequestHandler
            {
                private readonly System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
    
                protected override IResponseFilter GetResourceResponseFilter(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
                {
                    return new CefSharp.ResponseFilter.StreamResponseFilter(memoryStream);
                }
    
                protected override void OnResourceLoadComplete(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
                {
                    //You can now get the data from the stream
                    var bytes = memoryStream.ToArray();
    
                    if (response.Charset == "utf-8")
                    {
                        var str = System.Text.Encoding.UTF8.GetString(bytes);
                        Console.WriteLine("In OnResourceLoadComplete : " + str.Substring(0,10) + " <...>");
                    }
                    else
                    {
                        //Deal with different encoding here
                    }
                }
            }
    
            public class MyBasicRequestHandler : CefSharp.Handler.RequestHandler
            {
                protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
                {
                    Console.WriteLine("In GetResourceRequestHandler : " + request.Url);
                    //Only intercept specific Url's
                    if (request.Url == "http://cefsharp.github.io/" || request.Url == "https://cefsharp.github.io/")
                    {
                        return new MyCustomResourceRequestHandler();
                    }
                    //Default behaviour, url will be loaded normally.
                    return null;
                }
    
            }
    

    Start the app and happy to see this in the VisualStudio console ouput :

    In GetResourceRequestHandler : https://cefsharp.github.io/
    In OnResourceLoadComplete : <!DOCTYPE  <...>
    In GetResourceRequestHandler : https://fonts.googleapis.com/css?family=Ubuntu:400,500
    In GetResourceRequestHandler : https://cefsharp.github.io/stylesheets/stylesheet.css
    In GetResourceRequestHandler : https://cefsharp.github.io/stylesheets/github-light.css
    In GetResourceRequestHandler : https://sidecar.gitter.im/dist/sidecar.v1.js
    In GetResourceRequestHandler : https://cefsharp.github.io/images/logo2.png
    In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram1.png
    In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram2.png
    In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram3.png
    In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram4.png
    In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram5.png
    In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram7.png
    In GetResourceRequestHandler : https://cefsharp.github.io/images/diagram6.png
    In GetResourceRequestHandler : https://cefsharp.github.io/stylesheets/print.css
    In GetResourceRequestHandler : https://cefsharp.github.io/images/top-header.png
    In GetResourceRequestHandler : https://fonts.gstatic.com/s/ubuntu/v14/4iCs6KVjbNBYlgoKfw72.woff2
    In GetResourceRequestHandler : https://fonts.gstatic.com/s/ubuntu/v14/4iCv6KVjbNBYlgoCjC3jsGyN.woff2
    

    So my problem is solved ! Thanks again dear amaitland ;-)