Search code examples
javascriptc#getterdotnetbrowser

dotnetbrowser javascript interacting with c# this[string name]


I have a project that i am running .NET code inside. i need to use the existing objects and cannot modify them.

The class in c# that i am trying to use is

class Fields
{
   Hashtable list = new Hashtable();
   public Fields this[string Name]
   {
      get{
blah blah
      }
   }
}

I am attaching the object to JS window :

window = await _browser.MainFrame.ExecuteJavaScript<IJsObject>("window");
window.Properties["Data"] = _myObject;

when using this in the js environment, i can access everything i need to except i cannot use the getter of the Fields.

window.Data.Fields['123']

Is there something i doing wrong or is there a way to use the getter here?


Solution

  • You can try this approach:

    internal class Program
    {
        public static void Main()
        {
            using (IEngine engine = EngineFactory.Create())
            {
                using (IBrowser browser = engine.CreateBrowser())
                {
                    browser.Size = new Size(700, 500);
    
                    var myObject = new MyObject();
                    var window = browser.MainFrame.ExecuteJavaScript<IJsObject>("window").Result;
                    window.Properties["Data"] = myObject;
    
                    // 1. For JS, window.Data.Fields['123'] and window.Data.Fields[123] are equivalent.
                    // For C# and VB, this is not the case. To be able to handle numeric indices,
                    // DotNetBrowser will recognize if the parameter as a numeric index and try to look for
                    // the indexer with the integer parameter, which is not present in the Fields class.
                    var value = browser.MainFrame
                                                .ExecuteJavaScript("window.Data.Fields['123']")
                                                .Result;
                    Console.WriteLine($"\twindow.Data.Fields['123']: {value}");
    
                    // 2. Workaround: use the get_Item() method generated during compilation.
                    // It will accept a string as a parameter and return a proper result.
                    value = browser.MainFrame
                                    .ExecuteJavaScript("window.Data.Fields.get_Item('123')")
                                    .Result;
                    Console.WriteLine($"\twindow.Data.Fields.get_Item('123'): {value}");
    
                    // 3. The non-numeric index will be recognized as string and the corresponding
                    // indexer will be used.
                    value = browser.MainFrame
                                        .ExecuteJavaScript("window.Data.Fields['id']")
                                        .Result;
                    Console.WriteLine($"\twindow.Data.Fields['id']: {value}");
                }
            }
    
            Console.WriteLine("Press any key to terminate...");
            Console.ReadKey();
        }
        class Fields
        {
            readonly Hashtable list = new Hashtable();
            public string this[string Name]
            {
                get
                {
                    return list[Name]?.ToString();
                }
            }
    
            public void Add(string key, string value)
            {
                list[key] = value;
            }
        }
        private class MyObject
        {
            public MyObject()
            {
                Fields = new Fields();
                Fields.Add("123", "Test");
                Fields.Add("id", "Test2");
            }
    
            public Fields Fields { get; }
        }
    }