ActiveX加载的C# DLL返回JS数组时typeof显示未知类型求解
解决IE9中ActiveX返回数组typeof显示unknown的问题
我之前在做个人用的C# ActiveX DLL时,也碰到过和你一模一样的情况——返回字符串、布尔值都正常,可一返回数组,JS里typeof就显示unknown,折腾了好一阵才搞定。结合你的需求(已经知道JavaScriptSerializer的方向),给你整理几个实用的解决方案:
方案1:序列化JSON字符串(最推荐)
这是最稳妥的方式,把数组序列化成JSON字符串返回给JS,再在前端解析成数组,完美绕过IE9对CLR数组的互操作限制。
C#代码示例:
using System.Web.Script.Serialization; // 需要引用System.Web.Extensions程序集 [ComVisible(true)] public class MyActiveXClass { public string GetStringArray() { string[] arr = new string[] { "foo", "bar", "baz" }; JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(arr); } }
JS调用示例:
var activeXObj = new ActiveXObject("YourNamespace.MyActiveXClass"); var jsonStr = activeXObj.GetStringArray(); var arr = JSON.parse(jsonStr); console.log(typeof arr); // 现在会显示"object",而且可以正常遍历数组元素
注意:如果你的项目是.NET Framework 4.0及以上,直接引用System.Web.Script.Serialization即可;低版本需要手动添加System.Web.Extensions的引用。
方案2:使用COM兼容的集合类型
CLR的泛型List或普通数组在IE9的COM互操作中无法被正确识别类型,换成COM可见的ArrayList或者object[]数组,JS虽然typeof还是显示"object",但可以正常操作元素:
C#代码示例(用ArrayList):
using System.Collections; [ComVisible(true)] public class MyActiveXClass { public ArrayList GetArrayList() { ArrayList list = new ArrayList(); list.Add("item1"); list.Add("item2"); return list; } }
JS调用示例:
var activeXObj = new ActiveXObject("YourNamespace.MyActiveXClass"); var list = activeXObj.GetArrayList(); for(var i = 0; i < list.Count; i++){ console.log(list.Item(i)); // 可以正常获取元素 }
方案3:自定义COM可见的集合类
如果需要更灵活的操作,可以封装一个实现IEnumerable接口的COM可见类,让JS能通过for...in循环遍历:
C#代码示例:
using System.Collections; [ComVisible(true)] public class MyCustomCollection : IEnumerable { private string[] _items = new string[] { "a", "b", "c" }; public IEnumerator GetEnumerator() { return _items.GetEnumerator(); } // 可以额外添加Count、Item等属性方便JS调用 public int Count => _items.Length; public string Item(int index) => _items[index]; } [ComVisible(true)] public class MyActiveXClass { public MyCustomCollection GetCustomCollection() { return new MyCustomCollection(); } }
JS调用示例:
var activeXObj = new ActiveXObject("YourNamespace.MyActiveXClass"); var collection = activeXObj.GetCustomCollection(); console.log(collection.Count); // 输出3 console.log(collection.Item(0)); // 输出"a"
最后再提个小提醒:确保你的C#类、方法都标记了[ComVisible(true)],并且DLL已经用regasm.exe /codebase注册过,IE9的安全设置也允许ActiveX控件运行(毕竟是个人用,这个你应该已经搞定了)。
内容的提问来源于stack exchange,提问作者bosscube
相关产品推荐
相关产品推荐

