好的,这是非常适合的,但我希望有人可以帮助我。另外,我对CSharp很满意,但对JScript和COM缺乏经验。
问题是这个。我正在支持用CSharp编写并作为COM对象公开的应用程序组件。它公开了几个公共方法,它们由客户端应用程序调用。客户端都是用JScript编写的经典ASP脚本文件。 我想向COM对象添加一个新的公共方法,该方法返回一组对象。
我能够返回一个对象并访问它的属性。例如,在这个C#签名......
ResultObject GetResult();
... ResultObject是一个具有简单属性且没有逻辑的POCO。我可以使用以下JScript访问它的属性:
var oMyObject = Server.CreateObject("MyNamespace.MyObject");
var result = oMyObject.GetResult();
Response.Write("<br /><i>('" + result.Value + "', '" + result.ID + "')</i>");
当我尝试从C#返回一个简单的ResultObject数组时......
ResultObject[] GetResults();
...并从JScript中访问它......
var oMyObject = Server.CreateObject("MyNamespace.MyObject");
var results = oMyObject.GetResults();
for (var i = 0; i < results.length; i++) {
Response.Write("<br /><i>('" + results[i].Value + "', '" + results[i].ID + "')</i>");
}
...调用脚本时出现以下错误:
Microsoft JScript运行时错误“800a138f”
'results.length'为null或不是对象
此外,尝试JScript“typeof results”会给我一种“未知”。
如何从作为COM对象公开的CSharp类返回集合(数组,IEnumerable等)并从经典ASP JScript访问它?
答案 0 :(得分:2)
你可以做的是返回一个手工制作的集合,如下所示:
[ComVisible(true)] // may be optional depending on your other assembly settings
public class ResultList
{
private List<Result> _innerList;
internal ResultList(...parameters...)
{
_innerList = ...
}
public int Count
{
get
{
return _innerList.Count;
}
}
public Result this[int index] // will be named "Item" in COM's world
{
get
{
return _innerList[index];
}
}
}
你可以像这样使用:
var results = oMyObject.GetResults();
for (var i = 0; i < results.Count; i++) {
Response.Write("<br /><i>('" + results.Item(i).Value + "', '" + results.Item(i).ID + "')</i>");
}
答案 1 :(得分:2)
好吧,在提出这个问题之后,StackOverflow提出了一些相关的问题,这些问题共同帮助我解决了问题。
关于相关问题的This answer显示了我需要在C#中进行的更改。显然,COM更喜欢使用它所谓的SAFEARRAY。返回SAFEARRAY非常简单。我只是在C#中更改了我的方法的返回类型以返回'对象',并添加了一个属性来指导COM如何编组返回值:
[return: MarshalAs(UnmanagedType.Struct, SafeArraySubType = VarEnum.VT_ARRAY)]
object GetResults();
然后我在从这个C#方法返回之前对我的数组做了一些奇特的渲染:
ResultObject[] retv = //create and populate the return value array
return retv.Cast<object>().ToArray();
这让我回到了COM友好的SAFEARRAY。
(注意,“MarshalAs”属性似乎不是必需的。我的代码没有它的行为,但我喜欢澄清它提供的关于返回值的“文档”。)
然后this answer显示了我需要在JScript中进行的更改。看起来JScript与SAFEARRAY并不是很好。幸运的是,您可以使用“toArray()”方法轻松将其转换为JScript友好的数组:
var results = oMyObject.GetResults().toArray();
现在所有人都表现得很好。