【问题标题】:How to pass a Classic ASP Scripting.Dictionary to a C# COM Class Library?如何将经典 ASP Scripting.Dictionary 传递给 C# COM 类库?
【发布时间】:2014-09-12 15:45:25
【问题描述】:

我正在开发一个交给我的经典 ASP 应用程序,我必须使用它。我想使用仅在 .NET 框架中的组件。我需要制作一个 C# 类库,它可以执行可以通过经典 ASP 上的 COM 调用的 .NET 代码。

我想将一个经典的 ASP 字典传递给 C# com 组件。最好的情况是通过字典。我在我的 C# 代码中添加了来自 com 的 Scripting.Dictionary 作为参考。

这是我当前的代码。

经典 ASP:

Set test = Server.CreateObject("Reporting") 'This is my custom Object
Set dic = Server.CreateObject("Scripting.Dictionary")
dic.Add "Test", 1
test.GetReport 1, dic

C#:

public byte[] GetReport(int Report_Type_Requested, Scripting.DictionaryClass Report_Params)
        {
            try
            {
                return report.GetReport(Report_Params);
            }
            catch (Exception e)
            {               
                throw e;
            }                       
        }

但是当我运行它时,我得到:

Message = "Unable to cast COM object of type 'System.__ComObject' to class type 'Scripting.DictionaryClass'. COM components that enter the CLR and do not support IProvideClassInfo or that do not have any interop assembly registered will be wrapped in the __ComObject ...

我也试过这个,但似乎没有用:

public byte[] GetReport(int Report_Type_Requested, Dictionary Report_Params)
            {
                try
                {
                    return report.GetReport(Report_Params);
                }
                catch (Exception e)
                {               
                    throw e;
                }                       
            }

我认为这个可能有效,但它告诉我你不能施放它:

public byte[] GetReport(int Report_Type_Requested, object Report_Params)
                {
                    try
                    {
                        return report.GetReport((Scripting.DictionaryClass)Report_Params);
                    }
                    catch (Exception e)
                    {               
                        throw e;
                    }                       
                }

我怎样才能完成我想做的事情?

谢谢。

编辑:

我尝试在得到“无效的过程调用或参数”时使用 IDictionary,如下所示:

 public byte[] GetReport(int Report_Type_Requested, IDictionary Report_Params)
                    {
                        try
                        {
                            return report.GetReport(Report_Params);
                        }
                        catch (Exception e)
                        {               
                            throw e;
                        }                       
                    }

编辑 2:

我尝试使用 Scripting.IDictionary 来更好地指定它。我得到了同样的错误“无效的过程调用或参数”:

public byte[] GetReport(int Report_Type_Requested, Scripting.IDictionary Report_Params)
                        {
                            try
                            {
                                return report.GetReport(Report_Params);
                            }
                            catch (Exception e)
                            {               
                                throw e;
                            }                       
                        }

编辑 3:

我添加了获取报告的代码。我不断将 GetReport 参数更改为我正在测试的任何内容。

public byte[] GetReport(Scripting.IDictionary Report_Params)
        {
           return null;
        }

【问题讨论】:

  • 尝试Scripting.IDictionary 而不是Scripting.DictionaryClass
  • 函数参数的IDictionary?然后我是否将它转换为函数内部的字典类,或者我可以像那样正常使用它吗?
  • 只要你从脚本中传递它,就可以尝试像那样使用它,而不是强制转换。
  • 我似乎也没有在这方面取得任何成功。我在上面的编辑中发布了代码。
  • 不仅仅是IDictionary(可能是this),还有Scripting.IDictionary

标签: c# dll dictionary asp-classic com


【解决方案1】:

以下应该可以工作(当然你需要引用“Microsoft Scripting Runtime”COM 对象):

    public byte[] GetReport(int Report_Type_Requested, object Report_Params)
    {
        Scripting.Dictionary dic = (Scripting.Dictionary)Report_Params;
        foreach (string key in dic)
        {
            object value = dic.get_Item(key);
        }
        ...
    }

【讨论】:

  • 这样做是什么让我“无法将类型为'System.__ComObject'的 COM 对象转换为类类型'Scripting.DictionaryClass'。进入 CLR 且不支持 IProvideClassInfo 的 COM 组件或没有注册任何互操作程序集将被包裹在 __ComObject ..." 错误
  • 对不起,我从原始问题的错误中复制并粘贴了该错误,但仅使用 Scripting.Dictionary 时我仍然遇到相同的错误。
  • 它对我来说很好用。您应该共享一个重现项目。
【解决方案2】:

我用以下方法修复了它:

似乎当一个对象从 Classic ASP 传递到一个 COM 对象时,它必须作为一个对象传递,因此最终的定义是:

public byte[] GetReport(int Report_Type_Requested, object Report_Params)

为了将该对象转换为字典对象,我从谷歌搜索中发现了 Marshal 类:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal(v=vs.100).ASPX

制作我需要的线:

Scripting.DictionaryClass Report_Dictionary = (Scripting.DictionaryClass)Marshal.CreateWrapperOfType(Report_Params, typeof(Scripting.DictionaryClass));

然后我就可以在我的代码中使用字典了。

我还能够使用这种技术通过 COM 引入 ADODB.Recordsets。

【讨论】:

    猜你喜欢
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 2011-10-09
    • 1970-01-01
    相关资源
    最近更新 更多