【问题标题】:WebBrowser control: window.external access arrayWebBrowser 控件:window.external 访问数组
【发布时间】:2014-06-22 20:56:59
【问题描述】:

我正在尝试在 Javascript 中从 C# 访问数组。

这是 JavaScript 代码:

var testArray = window.external.testfunction();
for(var i = 0; i < testArray.length; i++) {
    alert(testArray[i]);
}

我使用分配给 ObjectForScripting 属性的以下 C# 对象对其进行了测试:

[ComVisible(true)]
public class TestObject
{
    public string[] testfunction()
    {
        var test = new string[1];
        test[0] = "test";
        return test;
    }
}

在尝试访问 testArray.length 时,它会引发 JavaScript 错误,提示“预期功能”。

那么如何将数组返回给 JavaScript 代码呢?

JavaScript 代码已修复(我无法修改)。因此,该函数将使用 window.external.testfunction() 调用,并且 JavaScript 代码需要一个数组作为返回值。

我怎样才能从 C# 端实现这一点?

最好的问候,并感谢您对此提出任何想法

安德烈亚斯

【问题讨论】:

  • 最简单的方法是使用 Get/Set/Length 方法将您的 C# 数组包装到一个单独的对象中,然后将其返回给 JavaScript。这可能会给你一些想法:stackoverflow.com/a/20943173/1768303
  • 你好 Noseratio,我认为这行不通,因为 JavaScript 可能无法使用 testArray[i] 访问数组元素,是吗?正如我所写的,我无法更改 JavaScript 代码本身,我只能使用 C# 代码。但是真的没有办法将数组作为函数的返回值传递给 JavaScript 吗?
  • 如果你不能修改JavaScript,你将如何访问window.external?无论如何,您总是可以注入一些新的 JavaScript,在我的回答末尾检查更新。
  • 只是为了回答你的问题,为什么在 JS 代码中已经可以访问 window.external 虽然我无法修改它:这个 JS 代码在一个更大的项目中,它已经通过这个使用了一些外部数据window.external 接口。我现在只需要模拟或模拟这个接口,以便从 C# 端进行测试。这就是为什么我不能修改JS代码的原因,但是window.external已经到位,也不能更改。

标签: c# javascript webbrowser-control window.external


【解决方案1】:

我认为这行不通,因为 JavaScript 可能会 无法使用 testArray[i] 访问数组元素,确实 是吗?

我在评论中提到的对象将是最简单的方式,但您将无法从 JavaScript 以 testArray[i] 的形式访问其元素。

hard 方法是在 C# 中实现一个模拟 JavaScript 数组对象的类(因此它作为 COM IDispatchEx 对象暴露给 JavaScript,并且可以作为 testArray[i] 访问)。这样的 C# 类需要实现 IReflectIExpando 托管接口。如果你想走这条路,我在这里发布了更多细节:

这是另一种方法。尽管您无法修改页面现有的 JavaScript,但您仍然可以inject some new JavaScript code,并随心所欲地使用它。

【讨论】:

  • 我可能需要采用 IExando 方式。因此,我检查了您的示例,第二个链接是从 IReflect 开始的一个非常好的示例,但我没有找到 IExpando 实现的示例(也在 Google 上搜索时)。你知道一个关于如何“模拟”数组行为的例子 - 所以通过testArray[i] 访问元素 - 通过使用这个接口?
  • @ab-tools, IReflect 对于“固定”数组可能就足够了(即,JavaScript 不能添加新元素,但可以读取/写入现有元素)。请记住,元素索引映射到名称为"0""1" 等的属性。如果要向数组添加新元素,则需要IExpando。我找不到IExpando 的示例,但我确定我过去编写过代码并且它有效。
  • 您好 Noseratio,首先感谢您的大力支持!我绝对不需要在这里添加任何新元素——所以 IReflect 就足够了。但是我不能让它与您链接中的示例一起使用:我应该在那里使用什么作为目标对象?基本上我没有目标对象——我只想模拟数组行为。如果您能在这里给我一些提示,那就太好了。再次非常感谢您提前提供的帮助!
  • 仍然将您的答案标记为已接受,因为您给了我提示(使用 IReflect)我需要找到正确的方法。再次感谢您!
【解决方案2】:

我现在真的可以自己使用 IReflect 界面了! :-)

您需要自己实现GetPropertiesInvokeMember 方法:在GetProperties 中,您需要确保返回名称为“length”的属性和“0”的属性,直到length-1的数组。在InvokeMember 中,您只需检查 JavaScript 想要调用哪个方法并返回正确的结果。

我遇到的最大问题是 PropertyInfo 类是抽象的 - 所以我无法从中创建新对象。所以我需要从中派生一个自己的类并使用它来返回自定义属性名称。

【讨论】:

    猜你喜欢
    • 2014-06-19
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-01
    • 2012-06-14
    相关资源
    最近更新 更多