Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / VBScript
Article

.NET COM+ Interop Component with Classic ASP (Part I)

Rate me:
Please Sign up or sign in to vote.
4.80/5 (14 votes)
25 Sep 2008CPOL8 min read 159.5K   1.7K   46   24
Call a .NET COM+ Interop component with Classic ASP.

Introduction

It was going a little boring for a while, and then I got something interesting to work on – "Classic ASP application needs to call a new .NET component(s)"; to be honest, the development of the .NET component is decided so that one day the application will be fully converted into .NET. In this article, I'll try to keep the discussion to the practical aspects of software development and keep it simple for developers to follow with a minimum distraction of buzz words.

Background

I have worked on similar assignments before with little difference; the front end application was in .NET, and the components were in C++/VB6. I started working on it right away, and tumbled many times on various issues. Everything is right if the end is right.

Writing the C# component was easy as walking on green grass bare foot, though log4net posed some issues with the config file; eventually, I moved to the ASP application to consume the C# component. Live Free or Die Hard; these are the two options, either use only .NET components, or use both with benefits of both, without the overhead of having to convert everything to .NET.

There are many options, and one should decide after checking out the performance, style, ease of development, and ease of debugging; believe me, different organizations have completely different styles, and still business goes as usual, i.e., there is no wrong or right way, and all depends on the business and the requirements.

One option is to use tlbexp to get the DLL ready for the ASP application. It needs another step of registering the DLL with regsvr32; the registration is required as you might remember, while working with the C++/VB projects.

The second option is to register and import with one command; regasm: this command creates the type library and registers the assembly. Registering the assembly is required as the VB6/C++ code registers with binary compatibility.

The third option is to create the service using regsvcs; regsvcs creates the type lib, registers the DLL, and creates the COM+ service. I like this as you can reap a lot of COM+ benefits like transaction queuing etc. Please refer to COM+ books for further reading, and as I mentioned before, I'll try to keep the theory out.

The first and the second options are really the same, so in a way, there are two options, and I started with the first, and liked the second later on, as I was working on this project. I have decided purely based on my knowledge, plus the need that the code is maintained by developers more familiar with VB than .NET.

I have many layers, and I was not sure if I needed to create a type library and/or register the lower layers; similarly, should I register the other assemblies referenced or used in the exposed assembly. I guessed that it's not required as eventually it will be running the .NET assembly; TLB is just a CCW wrapper, and doesn't include the rest of the assembled/binary code.

Let's Code

Ready? Let's jump right in....

The assembly needs to be consumed as a COM+ service, and here are the steps required to make it worthy. These steps are not sequential, and you can change the order as it fits your needs, but some of the steps depend on the previous steps.

Step 1: Add a reference to InteropServices; this enables your component to be visible to COM and the Enterprise library, and provides core COM+ abilities. ServicedComponent is part of the EnterpriseServices namespace, and you will see in the next steps that the class must inherit ServicedComponent. Add the following lines on the top of the class after the other using statements.

C#
using System.Runtime.InteropServices; 
using System.EnterpriseServices;

By adding these references, you will get intellisense for the rest of the steps. ;-)

Step 2. Assign the name, description, activation, transaction, and the rest of the information for the assembly before the namespace tag. You can give any name, and by default, it will use the name of the project. There are a whole bunch of options available, and I have picked the bare necessities for my sloppy code. You only need to add these to classes you are exposing with COM+. Rest of the classes used by this class can stay clean, and these entries are not required again in the project.

C#
[assembly: ApplicationName("JayTest")]
[assembly: Description("Jay Test business layer com+")]
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(false, 
           AccessChecksLevel = AccessChecksLevelOption.ApplicationComponent)]

namespace busLayer
{

The GUID can be created easily using the Create GUID tool in VS2005.

Step 3: GUID; as you remember, for binary compatibility, the GUID on the class is required to make the class have a unique class ID. Don't worry about ServicedComponent as it is explained in the following steps.

C#
[GuidAttribute("ADF0D549-D84B-422c-A15E-5B22C1E35FB5")]

public class JayClass :ServicedComponent
{

Screenshot - step2.jpg

Step 4: Make the DLL COM visible. Of course, you need that, and place the following code in ApplicationInfo.cs. It is self-explanatory, and should be set as true; if you don't do this, the assembly can't be used, and you will get an error message in the CreateObject call.

C#
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.

[assembly: ComVisible(true)]

Step 5: ServicedComponent: This topic can take the whole chapter or a book, but following the KISS principle, your COM+ exposed class must inherit ServicedCompnent; otherwise, while creating the service, you will get a message that there are no serviceable components. See Step 3 for the code.

Step 6: Sign your assembly with a strong name key file. You can either select a new one on the project properties screen - Signing tab, or generate a strong name key using sn.exe.

Step 7: Compile the code, and hope you got it all right, and you will see the component in Component Services. Oh oh… there is a tip to create a COM+ component after successful compilation.

On the Properties screen, click on Build Events. Enter "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regsvcs /u $(TargetFileName)" for Pre-build event, and "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regsvcs $(TargetFileName)" for Post-build event. As you know or guessed, /u is to un-register the component, and pre-build event un-registers the component, and the post-build registers the component. The whole path is required to run regsvcs – a bug.

For the first time, the unregistered will fail as the component doesn't exist, so comment the pre-build event by keying rem in the front. You can also run these commands from the VS2005 command prompt. I could put both commands in post build, but noticed that the compile fails as the component is being used in other processes.

Screenshot - Step7-1.jpg

After registration, open Component Services to verify that your component does exist in the list of COM+ applications.

Screenshot - Step7-2.jpg

You can open Component Services using Start – Settings – Control Panel – Administrative Tools – Component Services.

The + sign on the component will be stationary, which indicates that the component is there not running, and there is no need to start as it will start automatically when it is called for the first time, or you can start by right click and Start. You can right click on the COM+ component and click Properties to set properties like user ID for running the component, pool size, security, queuing etc.

I usually set pooling based on the performance benchmarking, and you can play with it on the server to compare performance. You can also make it a service, and it will show in Services along the other services on your machine. Again, not going in to details as you can read about those in many books and articles.

Step 8: Last but not the least, call the COM+ component from an application.

Create an ASP page and the code to create an object of the COM+ component, using:

VBScript
dim oBus
set oBus = server.CreateObject("busLayer.JayClass")

Once you create the object, call the method you want, like…

VBScript
rtnVal = oBus.MyLog("asp msg")

This part is mundane, and I hope everybody understands old VBScript.

I am using the log4net .NET component to log the messages; for details of the log4net open source application, go here which will redirect to the new owner Apache.

There is no need to either copy your assembly to the GAC or copy any DLL to the system32 folder.

All the log4net code is out of the scope of this article, and I'll write about it at some other time. The same applies for using VB6 components in .ENT applications, and I have called VB6/C++ components from .NET and think it is easier (just add a reference to the unmanaged component, or run tlbimp) than using a .NET component in VB6/VBScript, as the Registry issues will not raise their heads.

Your comments are appreciated, which can save some hours of my life fighting with the code, and will also help the rest of us.

In part II, I'll explain the debugging of the .NET COM+ component.

Points of Interest

Note on method overloading: method overloading will not work with COM+ as the name is automatically appended by a suffix, and when you try to call the method, you will get an error message indicating that the parameters or parameter types are incorrect. Another hard to figure out issue, and took a few hours of my life (;-|).

Like to debug your application with a web or test project? Read Part II.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
United States United States
I am a software architect/developer, having 15 years of design/development experience. Currently working in large financial corporation, architecting .NET applications and coding using C#, ASP.NET, Java Script etc..

MS Computers, MCP, MCTS: .NET Framework 2.0 Web Applications.

Comments and Discussions

 
QuestionRegarding use of .net component through ASP Pin
Member 26286779-Sep-15 22:57
Member 26286779-Sep-15 22:57 
QuestionExcellent Pin
R. Giskard Reventlov17-Mar-15 6:02
R. Giskard Reventlov17-Mar-15 6:02 
QuestionRegistering .net dll having enterprise library using com to access in Classic ASP Pin
Member 887505323-Apr-12 21:19
Member 887505323-Apr-12 21:19 
QuestionQuestion: How to register on SERVER ? Pin
shtapi119-Jul-10 5:05
shtapi119-Jul-10 5:05 
AnswerRe: Question: How to register on SERVER ? Pin
tomcat120-Jul-10 15:44
tomcat120-Jul-10 15:44 
yes you got it right, you can create msi by right clicking the component and use export (I guess) option.
Jay

GeneralRe: Question: How to register on SERVER ? Pin
UAS767-Jan-14 23:52
UAS767-Jan-14 23:52 
GeneralThe component works, but drops all sessions Pin
tony4178014-Jul-10 12:27
tony4178014-Jul-10 12:27 
Generalmultiple calls generates error Pin
AsafMeir21-Sep-09 1:25
AsafMeir21-Sep-09 1:25 
GeneralGood Job Pin
dan!sh 4-Feb-09 1:04
professional dan!sh 4-Feb-09 1:04 
Generalapp.config Problem Pin
Nic Allen26-Jan-09 2:37
Nic Allen26-Jan-09 2:37 
GeneralRe: app.config Problem Pin
tomcat12-Feb-09 8:36
tomcat12-Feb-09 8:36 
GeneralRe: app.config Problem Pin
belzu16-Mar-09 6:10
belzu16-Mar-09 6:10 
GeneralRe: app.config Problem Pin
tomcat116-Mar-09 17:20
tomcat116-Mar-09 17:20 
QuestionHow can I debug the .NET serviced component when I call it from classic ASP Pin
Sascha Kruening29-May-08 8:47
Sascha Kruening29-May-08 8:47 
AnswerRe: How can I debug the .NET serviced component when I call it from classic ASP Pin
tomcat125-Sep-08 4:11
tomcat125-Sep-08 4:11 
GeneralWorks for ASP.NET but not ASP Pin
imterpsfan22-Apr-08 9:04
imterpsfan22-Apr-08 9:04 
GeneralRe: Works for ASP.NET but not ASP [modified] Pin
tomcat125-Sep-08 5:04
tomcat125-Sep-08 5:04 
GeneralInvalid class string... [modified] Pin
mr.Gargol26-Mar-08 4:17
mr.Gargol26-Mar-08 4:17 
GeneralRe: Invalid class string... Pin
tomcat125-Sep-08 4:06
tomcat125-Sep-08 4:06 
GeneralRe: Invalid class string... Pin
mr.Gargol3-Oct-08 0:49
mr.Gargol3-Oct-08 0:49 
GeneralRe: Invalid class string... Pin
cakewalkr719-Dec-08 5:27
cakewalkr719-Dec-08 5:27 
GeneralRe: Invalid class string... Pin
cakewalkr719-Dec-08 5:53
cakewalkr719-Dec-08 5:53 
GeneralRe: Invalid class string... Pin
tomcat119-Dec-08 8:05
tomcat119-Dec-08 8:05 
GeneralRe: Invalid class string... Pin
tomcat119-Dec-08 7:56
tomcat119-Dec-08 7:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.