How should an array be passed to a Javascript function from C#?

后端 未结 4 958
误落风尘
误落风尘 2021-02-02 17:59

I use a WebBrowser object from WPF and I\'m calling some Javascript code in the page loaded in the browser like this:

myWebBrowser.InvokeScript(\"myJsFunc\", new         


        
相关标签:
4条回答
  • 2021-02-02 18:43

    It's not solving the issue itself but it solves the problem if you have only one array to pass: you can send an arbitrary number of parameters to a JavaScript function, and access them through the arguments special variable. It becomes analogous to a function accepting a variable number of arguments, with the same advantages and problems (for instance, you have to pass the array last, and as mentioned earlier you can only pass one).

    Here's an example JavaScript function:

    function foo()
    {
        var stringArgs = [];
        for (var i = 0; i < arguments.length; i++)
            stringArgs.push(arguments[i]);
    
        // do stuff with stringArgs
    }
    

    And you'd call it from C# like this:

    List<string> arguments = new List<string>();
    arguments.Add("foo");
    arguments.Add("bar");
    webBrowser.InvokeScript("foo", arguments.ToArray());
    
    0 讨论(0)
  • 2021-02-02 18:45

    You need to convert the array to a JS array first, something that looks like this:

    ["John", "Bob", "Sue"] // literal array
    

    Two examples follow:

    StringBuilder sb = new StringBuilder();
    string[] stringArray = bar.ToArray<string>();
    
    //Build the JS array.
    sb.Append( "[");
    for (int i = 0; i < stringArray.Length; i++)
    {
        sb.AppendFormat( "'{0}', ", stringArray[i] );
    
    }
    sb.Append( "]");
    
    
    // Now send the array to the JS function.
    myWebBrowser.InvokeScript("myJsFunc", new object[] { foo.Text, sb.ToString() });
    

    You may want to remove the trailing , as well. Don't forget to import the appropriate libraries for StringBuilder, which I think is System.Text.StringBuilder;

    or use, example two:

    string[] stringArray = bar.ToArray<string>();
    
    // or simpler to use string join.
    string jsArray = "[" + String.Join( ",", stringArray ) + "]";
    //
    myWebBrowser.InvokeScript("myJsFunc", new object[] { foo.Text, jsArray });
    
    0 讨论(0)
  • 2021-02-02 18:51

    In case you really want to squeeze every bit of performance out of the code you can avoid the deserialization by means of eval inside javascript. The concept is to structure the call like this:

    ((IHTMLWindow2)webBrowserControl.Document.Window.DomWindow).execScript("var returnValue = someFunction([ 'abc', 'xyz', '1', '2', '3' ], { foo: 'xyz', bar: 1 });"
    

    Notice that we use .execScript which makes all the difference in the world. This is because contrary to .InvokeScript which would forcefeed the javascript method with string based arguments (which is what forces you to use eval on the javascript side), .execScript() gives us the ability to write arbitrary javascript code including what you see above (notice that the arguments are an explicit javascript array and a bag of properties). Now we can directly code arrays and objects and write them as arguments. In order to do that we just use Newtonsoft.Json to serialize arrays and objects:

    class Test {
         public string foo;
         public int bar;
    }
    ((IHTMLWindow2)webBrowserControl.Document.Window.DomWindow).execScript("var returnValue = someFunction(" +
    JsonConvert.SerializeObject((new List<object>(2) { "abc", "xyz", 1, 2, 3 }).ToArray()) + ", " + JsonConvert.SerializeObject(new Test() { foo = "xyz", bar = 1 }) + ");");
    

    Another thing is retrieving the resulting returned value:

    string result = (string)webBrowserControl.Document.InvokeScript("eval", new object[] { @"returnValue;" }));
    

    For your convenience you might want to write a utility method which iterates over the given parameters and serializes them properly, invokes the function and then retrieves the returned value.

    0 讨论(0)
  • 2021-02-02 19:01

    Maybe pass it as a json string instead and parse it in the js function

    var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    var json = serializer.Serialize(bar.ToArray<string>());
    
    myWebBrowser.InvokeScript("myJsFunc", new object[] { foo.Text, json });
    

    js:

    function myJsFunc(json) {
       var data = JSON.parse(json);
       // do something with it.
    }
    

    http://blogs.microsoft.co.il/blogs/pini_dayan/archive/2009/03/12/convert-objects-to-json-in-c-using-javascriptserializer.aspx

    0 讨论(0)
提交回复
热议问题