如何将数组从C#传递给Javascript函数?

时间:2011-07-08 04:18:29

标签: c# javascript webbrowser-control

我使用WPF中的WebBrowser对象,我在浏览器中加载的页面中调用了一些Javascript代码,如下所示:

myWebBrowser.InvokeScript("myJsFunc", new object[] { foo.Text, bar.ToArray<string>()});

现在,js函数应该迭代第二个参数(字符串数组)的元素并相应地执行操作。唯一的问题是该参数似乎不会作为js数组传递。

例如,

alert(typeof theArray);

提醒“未知”。

从CSharp调用js函数时,将数组作为参数传递的正确方法是什么?

4 个答案:

答案 0 :(得分:13)

可能将其作为json字符串传递,并在js函数中解析它

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

答案 1 :(得分:5)

它没有解决问题本身,但是如果你只有一个数组要通过它就可以解决问题:你可以向JavaScript函数发送任意数量的参数,并通过arguments特殊变量访问它们。它变得类似于接受可变数量的参数的函数,具有相同的优点和问题(例如,你最后传递数组,并且如前所述,你只能传递一个)。 / p>

这是一个JavaScript函数示例:

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

    // do stuff with stringArgs
}

你可以用C#这样称呼它:

List<string> arguments = new List<string>();
arguments.Add("foo");
arguments.Add("bar");
webBrowser.InvokeScript("foo", arguments.ToArray());

答案 2 :(得分:4)

如果您真的希望从代码中挤出所有性能,可以通过javascript中的eval避免反序列化。这个概念就像这样构建调用:

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

请注意,我们使用.execScript,它在世界上有所不同。这是因为与.InvokeScript相反,它会强制使用基于 string 的参数强制javascript方法(这迫使你在javascript端使用eval),。execScript()使我们能够任意写入javascript代码包括你在上面看到的内容(注意参数是一个显式的javascript数组和一包属性)。现在我们可以直接编码数组和对象,并将它们写为参数。为此,我们只使用Newtonsoft.Json来序列化数组和对象:

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 }) + ");");

另一件事是检索返回的结果值:

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

为方便起见,您可能希望编写一个实用程序方法,该方法迭代给定的参数并正确地序列化它们,调用该函数然后检索返回的值。

答案 3 :(得分:3)

首先需要将数组转换为JS数组,如下所示:

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

以下两个例子:

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() });

您可能还想删除尾随。不要忘记为StringBuilder导入适当的库,我认为它是System.Text.StringBuilder;

或使用,例二:

string[] stringArray = bar.ToArray<string>();

// or simpler to use string join.
string jsArray = "[" + String.Join( ",", stringArray ) + "]";
//
myWebBrowser.InvokeScript("myJsFunc", new object[] { foo.Text, jsArray });