应该如何将数组从 C# 传递给 Javascript 函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6619931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How should an array be passed to a Javascript function from C#?
提问by Anthony Vallée-Dubois
I use a WebBrowser object from WPF and I'm calling some Javascript code in the page loaded in the browser like this:
我使用 WPF 中的 WebBrowser 对象,并在浏览器中加载的页面中调用一些 Javascript 代码,如下所示:
myWebBrowser.InvokeScript("myJsFunc", new object[] { foo.Text, bar.ToArray<string>()});
Now, the js function is supposed to iterate over the elements of the second parameter (an array of strings) and do stuff accordingly. The only issue is that the parameter seems not to be passed as a js array.
现在,js 函数应该遍历第二个参数(一个字符串数组)的元素并相应地做一些事情。唯一的问题是该参数似乎没有作为 js 数组传递。
For example,
例如,
alert(typeof theArray);
alerts "Unknown".
警报“未知”。
What is the proper way to pass an array as a parameter when invoking a js function from CSharp?
从 CSharp 调用 js 函数时,将数组作为参数传递的正确方法是什么?
回答by Ilia Choly
Maybe pass it as a json string instead and parse it in the js function
也许将其作为 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:
js:
function myJsFunc(json) {
var data = JSON.parse(json);
// do something with it.
}
回答by zneak
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 haveto pass the array last, and as mentioned earlier you can only pass one).
它本身并不能解决问题,但如果您只有一个数组要传递,它就可以解决问题:您可以向 JavaScript 函数发送任意数量的参数,并通过arguments
特殊变量访问它们。它变得类似于接受可变数量参数的函数,具有相同的优点和问题(例如,您必须最后传递数组,而如前所述,您只能传递一个)。
Here's an example JavaScript function:
下面是一个 JavaScript 函数示例:
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:
你可以像这样从 C# 调用它:
List<string> arguments = new List<string>();
arguments.Add("foo");
arguments.Add("bar");
webBrowser.InvokeScript("foo", arguments.ToArray());
回答by XDS
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:
如果您真的想从代码中挤出每一点性能,您可以通过在 javascript 中使用 eval 来避免反序列化。这个概念是像这样构造调用:
((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 stringbased 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:
请注意,我们使用了 .execScript,它使世界变得与众不同。这是因为与 .InvokeScript 会使用基于字符串的参数强制馈送 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 }) + ");");
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.
为方便起见,您可能希望编写一个实用程序方法,该方法迭代给定的参数并正确序列化它们,调用函数然后检索返回值。
回答by b01
You need to convert the array to a JS array first, something that looks like this:
您需要先将数组转换为 JS 数组,如下所示:
["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;
您可能还想删除尾随 。不要忘记为 StringBuilder 导入适当的库,我认为是 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 });