Search code examples
c#jsondotnetbrowser

Returning Books JSON through dotnetbrowser


I am trying to return JSON string through XMlHTTPRequest response body. the problem is after the method create and instance of AjaxResourceHandler it will go ahead and execute the Get method before getting the required data which returns an empty string. What I want is to be able to return the response body as JSON string. and one more thing; can web browser do the same thing; if so how?

using AjaxRequest.Models;
using DotNetBrowser;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;

namespace AjaxRequest.Controllers
{
public class ValuesController : ApiController
{
    
  
    private static List<string> ajaxUrls = new List<string>();
    private static List<string> sourceDat = new List<string>();
    private static Browser browser;

    public ValuesController()
    {
        browser = BrowserFactory.Create();
        browser.Context.NetworkService.ResourceHandler = new AjaxResourceHandler();
        browser.Context.NetworkService.NetworkDelegate = new AjaxNetworkDelegate();

        browser.LoadURL("https://www.w3schools.com/xml/ajax_examples.asp");
        //browser.Dispose();
    }


    // GET api/values
    public IEnumerable<string> Get()
    {
        //Init();
        return sourceDat;

    }

    // GET api/values/5
    public string Get(int id)
    {
        
        return "value";
        
    }

    // POST api/values
    public void Post([FromBody]string value)
    {
    }

    // PUT api/values/5
    public void Put(int id, [FromBody]string value)
    {
    }

    // DELETE api/values/5
    public void Delete(int id)
    {
    }

    //private  void Init()
    //{
       
    //}

    public class AjaxResourceHandler : ResourceHandler
    {
        public bool CanLoadResource(ResourceParams parameters)
        {
            if (parameters.ResourceType == ResourceType.XHR && parameters.URL.Contains("https://123movies.is/ajax/v2_get_sources"))
            {

                ajaxUrls.Add(parameters.URL);

            }
            return true;
        }
    }

    public class AjaxNetworkDelegate : DefaultNetworkDelegate
    {
        public override void OnDataReceived(DataReceivedParams parameters)
        {
            if (ajaxUrls.Contains(parameters.Url))
            {

                PrintResponseData(parameters.Data);

            }
           
        }
        public void PrintResponseData(byte[] data)
        {

            var str = Encoding.UTF8.GetString(data);
            
            BookSource _sources = JsonConvert.DeserializeObject<BookSource>(str);
            sourceDat.Add(_sources.ToString());
            browser.Dispose();
            //source.Add(_sources);

            //return source;
        }

    }
    
}
}

Solution

  • You can try using a ManualResetEvent to block main thread until AJAX response is caught. The sample code below demonstrates how to implement this approach:

    using AjaxRequest.Models;
    using DotNetBrowser;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Text;
    using System.Threading;
    using System.Web.Http;
    
    namespace AjaxRequest.Controllers
    {
        public class ValuesController : ApiController
        {
    
            private static ManualResetEvent waitEvent;
            private static List<string> ajaxUrls = new List<string>();
            private static List<string> sourceDat = new List<string>();
            private static Browser browser;
    
            public ValuesController()
            {
                waitEvent = waitEvent = new ManualResetEvent(false);
                browser = BrowserFactory.Create();
                browser.Context.NetworkService.ResourceHandler = new AjaxResourceHandler();
                browser.Context.NetworkService.NetworkDelegate = new AjaxNetworkDelegate();
    
                browser.LoadURL("https://www.w3schools.com/xml/ajax_examples.asp");
                //browser.Dispose();
            }
    
            // GET api/values
            public IEnumerable<string> Get()
            {
                //Init();
                waitEvent.WaitOne();
                return sourceDat;
    
            }
    
            // GET api/values/5
            public string Get(int id)
            {
    
                return "value";
    
            }
    
            // POST api/values
            public void Post([FromBody]string value)
            {
            }
    
            // PUT api/values/5
            public void Put(int id, [FromBody]string value)
            {
            }
    
            // DELETE api/values/5
            public void Delete(int id)
            {
            }
    
            //private  void Init()
            //{
    
            //}
    
            public class AjaxResourceHandler : ResourceHandler
            {
                public bool CanLoadResource(ResourceParams parameters)
                {
                    if (parameters.ResourceType == ResourceType.XHR && parameters.URL.Contains("https://123movies.is/ajax/v2_get_sources"))
                    {
    
                        ajaxUrls.Add(parameters.URL);
    
                    }
                    return true;
                }
            }
    
            public class AjaxNetworkDelegate : DefaultNetworkDelegate
            {
                public override void OnDataReceived(DataReceivedParams parameters)
                {
                    if (ajaxUrls.Contains(parameters.Url))
                    {
    
                        PrintResponseData(parameters.Data);
    
                    }
    
                }
                public void PrintResponseData(byte[] data)
                {
    
                    var str = Encoding.UTF8.GetString(data);
    
                    BookSource _sources = JsonConvert.DeserializeObject<BookSource>(str);
                    sourceDat.Add(_sources.ToString());
                    waitEvent.Set();
                    browser.Dispose();
                    //source.Add(_sources);
    
                    //return source;
                }
    
            }
    
        }
    }
    

    As far as I know, there is no possibility to intercept AJAX responce directly in WebBrowser. There seems to be a workaround to intercept it through ObjectForScripting: catch ajax response data in web browser control C#