简体   繁体   中英

How to pass a Classic ASP Scripting.Dictionary to a C# COM Class Library?

I am working on a classic ASP application that was handed to me that I have to work with. I would like to use a component that is only in the .NET framework. I need to make a C# class library that can do the .NET code that can be called through the COM on classic ASP.

I would like to pass in a classic ASP dictionary into the C# com component. Best case would be to pass a dictionary of dictionaries. I have added Scripting.Dictionary from the com as a reference in my C# code.

Here is my current code.

Classic 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;
            }                       
        }

But when I run this I get:

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 ...

I've also tried this and it didn't seem to have worked:

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

I thought this one might work but it tells me you can't cast it:

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

How can I accomplish what I am trying to do?

Thank you.

EDIT:

I tried using IDictionary like the following at got "Invalid Procedure call or argument":

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

EDIT 2:

I tried using Scripting.IDictionary to specify it better. I got the same error "Invalid Procedure call or argument":

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

EDIT 3:

I added the code for Get Report. I keep changing the GetReport paramter to whatever I am testing.

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

The following should work (you need to reference the "Microsoft Scripting Runtime" COM object of course):

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

I fixed it with the following:

It seems that when an object gets passed from Classic ASP to a COM object, it MUST be passed as an object, therefore the final definition is:

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

In order to cast that object to the dictionary object I found out about the Marshal class from googling: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal(v=vs.100).ASPX

Making the line I needed:

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

I was then able to use the dictionary in my code.

I was also able to use this technique to bring in ADODB.Recordsets over the COM as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM