简体   繁体   English

如何在Classic ASP JScript中访问从CSharp COM对象返回的集合?

[英]How can I access a collection returned from a CSharp COM object in Classic ASP JScript?

Ok, this is pretty niche, but I'm hoping someone out there can help me. 好的,这是一个小众市场,但我希望外面有人可以帮助我。 Also, I'm comfortable in CSharp, but am inexperienced in JScript and COM. 另外,我对CSharp感到很舒服,但对JScript和COM则没有经验。

The problem is this. 问题是这样的。 I'm supporting an application component written in CSharp and exposed as a COM object. 我支持用CSharp编写并作为COM对象公开的应用程序组件。 It exposes several public methods, which are invoked by it's client applications. 它公开了几种公共方法,这些方法由其客户端应用程序调用。 The clients are all classic ASP script files written in JScript. 客户端都是用JScript编写的经典ASP脚本文件。 I'd like to add a new public method to the COM object which returns a collection of objects. 我想向COM对象添加一个新的公共方法,该方法返回对象的集合。

First, returning a single result object works fine... 首先,返回单个结果对象可以正常工作...

I'm able to return a single object and access it's properties. 我能够返回一个对象并访问其属性。 For example, in this C# signature... 例如,在此C#签名中...

ResultObject GetResult();

...ResultObject is a POCO with simple properties and no logic. ... ResultObject是具有简单属性且没有逻辑的POCO。 I'm able to access it's properties with the following JScript: 我可以使用以下JScript访问其属性:

var oMyObject = Server.CreateObject("MyNamespace.MyObject");
var result = oMyObject.GetResult();
Response.Write("<br /><i>('" + result.Value + "', '" + result.ID + "')</i>");

However, it breaks when I return an array... 但是,当我返回一个数组时,它会中断...

When I try and return a simple array of ResultObjects from C#... 当我尝试从C#返回一个简单的ResultObjects数组时...

ResultObject[] GetResults();

...and access it from JScript... ...并从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>");
}

...I get the following error when invoking the script: ...调用脚本时出现以下错误:

Microsoft JScript runtime error '800a138f' Microsoft JScript运行时错误'800a138f'

'results.length' is null or not an object 'results.length'为null或不是对象

Additionally, trying a JScript "typeof results" give me a type of "unknown". 另外,尝试JScript“ typeof results”给我一种“ unknown”类型。

How can I return a collection (array, IEnumerable, etc.) from a CSharp class exposed as a COM object and access it from classic ASP JScript? 如何从公开为COM对象的CSharp类返回集合(数组,IEnumerable等),并从经典的ASP JScript访问它?

What you can do is return a hand made collection, like this: 您可以做的是返回一个手工制作的收藏集,如下所示:

[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];
        }
    }
}

That you can use like this: 您可以这样使用:

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

Well, after asking this question, StackOverflow suggested some related questions that collectively got me to the solution. 好了,问了这个问题之后,StackOverflow提出了一些相关的问题,这些问题共同使我着手解决。

This answer on a related question showed changes I needed to make in C#. 有关一个相关问题的答案显示了我需要在C#中进行的更改。 Apparently COM prefers to work with what it calls a SAFEARRAY. 显然,COM更喜欢使用所谓的SAFEARRAY。 Returning a SAFEARRAY was pretty simple. 返回SAFEARRAY非常简单。 I just changed the return type of my method in C# to return an 'object', and added an attribute to guide COM on how to marshal the return value: 我只是在C#中更改了我的方法的返回类型以返回一个“对象”,并添加了一个属性以指导COM如何编组返回值:

[return: MarshalAs(UnmanagedType.Struct, SafeArraySubType = VarEnum.VT_ARRAY)]
object GetResults();

I then did some fancy casting on my array prior to returning from this C# method: 然后,在从此C#方法返回之前,我对数组进行了一些漂亮的转换:

ResultObject[] retv = //create and populate the return value array
return retv.Cast<object>().ToArray();

This got me to the point where I was returning a COM-friendly SAFEARRAY. 这使我回到了返回COM友好的SAFEARRAY的地步。

(Note, the "MarshalAs" attribute does not appear to be required. My code behaves without it, but I like the clarifying "documentation" it provides about the return value.) (请注意,“ MarshalAs”属性似乎不是必需的。我的代码在没有该属性的情况下也会起作用,但是我喜欢它提供的有关返回值的“文档”。)

Then this answer showed a change I needed to make in JScript. 然后, 此答案显示了我需要在JScript中进行的更改。 It seems JScript doesn't play well with SAFEARRAYs. 看来JScript与SAFEARRAYs搭配不好。 Fortunately you can easily convert it to a JScript-friendly array with the "toArray()" method: 幸运的是,您可以使用“ toArray()”方法轻松地将其转换为JScript友好数组:

var results = oMyObject.GetResults().toArray();

Now all is behaving as desired. 现在一切都按要求进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将整数数组从经典asp传递到ac#COM对象? - How do I pass an array of integers from classic asp to a c# COM object? 从JScript访问C#COM服务器 - C# COM server access from JScript 如何“替换”从 COM 返回的对象的接口到托管代码? - How can I "replace" the interface for an object returned from COM to managed code? 如何从非托管DLL访问csharp中包含动态数组的结构? - How can I access a struct in csharp that contains dynamic arrays, from an unmanaged DLL? 如何为经典ASP创建一个不会顺序阻止其他线程的DOTNET COM互操作程序集? - How can I create a DOTNET COM interop assembly for Classic ASP that does not sequentially block other threads? 我如何通过javascript将json数据推送到csharp对象列表? - how can i push json data to csharp list of object by javascript? 如何将参数从经典ASP传递到com组件 - How to pass parameters from Classic ASP to a com component 如何在asp-classic网页调用的.Net COM对象中编辑ConfigurationManager.App/ConnectionSettings - How do I edit ConfigurationManager.App/ConnectionSettings while in an .Net COM Object called by asp-classic web page 我如何在C#中访问返回对象的属性 - How can i access the properties of a returned object in c# 如何将电子邮件功能从ASP Classic迁移到ASP.NET? - How can I migrate email functionality from ASP Classic to ASP.NET?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM