There are already heaps of posts and guidance on how to make COM Callable wrappers out there but it would seem there is a lack of posts on how to then consume and use your API from Classic ASP

Recipe for success:

  • A .NET API that you would like to expose
  • regasm.exe (normally part of the Windows SDK, or as part of a standard Visual Studio installation)
  • A Classic ASP web site up and running

.NET API

So our .NET API is simple, but complex enough to show up a particular nuance to COM in VBScript. Two classes - one is used as a the parameter to a method on another:

[code language="csharp"]
var class1 = new Class1();
var class2 = new Class2();
class1.Method1(class2);
[/code]

So the key with your API is that if you are going to expose this stuff over COM you'll need to decorate your wrapper in such a way that a VBSCript client can deal with it.

[code language="csharp"]
using System.Runtime.InteropServices;
namespace ClassLibrary1
{
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ClassLibrary1.Class1")]
[Guid("004F61C7-5159-4812-B20A-68A537C33164")]
[ComVisible(true)]
public class Class1
{
public string Method1(Class2 foo)
{
return foo.Property1 + foo.Property2 + "1";
}
}

[ClassInterface(ClassInterfaceType.None)]
[ProgId("ClassLibrary1.Class2")]
[Guid("FF4B4FB3-98D2-4D0A-A4E3-94F64D0D5F77")]
[ComVisible(true)]
public class Class2
{
public string Property1
{
get { return "Hello "; }
}
public string Property2
{
get { return "Complex Parameterization"; }
}
}
}[/code]

Some things to note from the above code:

  • Each class should be marked as COM Visible and have its own GUID attribute
  • ProgID is optional, but it allows you to set how the VBScript client will create teh object by name.
  • Set the class interface type to none.

Registering and unregistering the .dll

Registration can get painful when you don't know what is going on. If you get weird behaviour while registering and unregistering, you will probably need to go and edit your registry to remove orphaned entries. In my experience this is only an issue if you aren't supplying your own GUIDs and Visual studio is generating new ones for you (via the Register for COM project setting - just turn it off) or you havent locked in your version number and that is going up every time you build.

Registation

regasm.exe "classlibrary1.dll" /tlb: "classlibrary1.tlb" /codebase

Unregistering

regasm.exe /u "classlibrary1.dll"

Incorporating into Classic ASP

Finally your classic ASP needs to look like this in order to access your COM library:

[code language="vb"]
Dim obj
Dim obj2
Dim parameter
Dim result

Set obj = Server.CreateObject("ClassLibrary1.Class1")
Set obj2 = Server.CreateObject("ClassLibrary1.Class2")

result = obj.Method1((obj2))
[/code]

Please note the double braces around the parameter on the final line there - my experience was that if you do not pass this by reference, then the following error will occur:

Microsoft VBScript runtime error: Invalid procedure call or argument: 'Method1'

Note that the permissions that IIS runs with will dictate access to your library location. Make sure it has read permissions. If that freaks you out, then use the GAC (see gacutil). If that freaks you out, then maybe COM & ClassicASP isn't for you. If passing by reference freaks you out, then you can instead change the type of Method1's parameter to dynamic (assuming your are on .NET 4+) and access it in a late bound fashion instead. Hope this saves somebody else some time, and that its saves some freaking out (because nobody wants that).