Registering a .NET DLL for COM visibility in ASP Classic - asp.net

We're trying to write a couple of applications. One ASP.NET site uses the .NET Assembly xxx.Elements.dll, which provides utility functions.
The other, a Classic ASP site, should also use the same DLL in order to use the same utility functions. (It will be used for encrypting data between the two sites).
Despite many attemps and Googling, we cannot get this working.
We have:
Applied ComVisibility to the Assembly.info and ensured there is a Guid:
[assembly: ComVisible(true)]
[assembly: Guid("ab96fbc3-aa39-4fb6-8628-13778445e503")]
We made sure our type ticks the boxes on type visibility by ensuring it has a default constructor, is ComVisible and has a Guid. We've also created a simplistic method for testing:
namespace xxx.Elements
{
[GuidAttribute("D3BE2C7D-7550-4da1-8F61-6871E193242F")]
[ComVisible(true)]
public class UrlUtility : IUrlUtility
{
public UrlUtility()
{
}
public string Test()
{
return "HellO";
}
}
}
Using the interface:
[GuidAttribute("D3BE2C7D-7550-4da1-8F61-6871E193242A")]
[ComVisible(true)]
public interface IUrlUtility
{
string Test();
}
We found this really useful (though non-resolving) post here to do this: warning MSB3391: does not contain any types that can be unregistered for COM Interop.
We have also checked the Regsiter for COM-Interop in the Project property pages.
This continues to output the warning:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3341,9): warning MSB3214: "D:\dev\yyy\xxx.Elements\bin\Release\xxx.Elements.dll" does not contain any types that can be registered for COM Interop.
when compiling. If we run REGASM xxx.Elements.dll /tlb directly, we get:
Microsoft (R) .NET Framework Assembly Registration Utility 4.0.30319.1
Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.
Types registered successfully
Assembly exported to 'D:\dev\yyy\IWW.Elements\bin\release\xxx.eleme
nts.tlb', and the type library was registered successfully
So a little confused about the ambiguity.
When we look in the registry, it does appear to register the .tlb correctly:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\TypeLib\{AB96FBC3-AA39-4FB6-8628-13778445E503}]
[HKEY_CLASSES_ROOT\TypeLib\{AB96FBC3-AA39-4FB6-8628-13778445E503}\1.1]
#="Elementary support library for xxx' products"
[HKEY_CLASSES_ROOT\TypeLib\{AB96FBC3-AA39-4FB6-8628-13778445E503}\1.1\0]
[HKEY_CLASSES_ROOT\TypeLib\{AB96FBC3-AA39-4FB6-8628-13778445E503}\1.1\0\win32]
#="D:\\dev\\yyy\\xxx.Elements\\bin\\Release\\xxx.Elements.tlb"
[HKEY_CLASSES_ROOT\TypeLib\{AB96FBC3-AA39-4FB6-8628-13778445E503}\1.1\FLAGS]
#="0"
[HKEY_CLASSES_ROOT\TypeLib\{AB96FBC3-AA39-4FB6-8628-13778445E503}\1.1\HELPDIR]
#="D:\\dev\\yyy\\xxx.Elements\\bin\\Release"
We have also registered the type in the GAC:
gacutil /i xxx.Elements.dll
and given it a strong name using:
sn -k xxx.Elements.snk
and included the name in the AssemblyInfo.cs file:
[assembly: AssemblyKeyFile(#"D:\dev\yyy\xxx.Elements\xxx.Elements.key")]
We have also applied the IUSR user Read permission to the registry keys:
HKEY_CLASSES_ROOT\TypeLib\{AB96FBC3-AA39-4FB6-8628-13778445E503}
HKEY_USERS\S-1-5-20\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones
(the last one was suggested here: Cannot instanciate .Net COM object in classic ASP/VBScript page (Error ASP 0177))
Despite all this, when we activate the object in the ASP page using the code:
dim urlUtility
set urlUtility = Server.CreateObject("xxx.Elements.UrlUtility")
' should return "Hello"
test=urlUtility.Test()
The process stops and when we debug into the W3WP process, we get the error:
Server object: 006~ASP 0177~Server.CreateObject Failed~800401f3
We have tried to check all the boxes, but we must be missing something. Any ideas, please?

I had a similar problem some time ago. I solved it by hosting the .NET component in the COM+ application server. This article suggests and describes the same. In addition to the article it maybe necessary to configure your assembly (It is running stand-alone, if you do as suggested). In this case you need a manifest and a config file in the applications root. Look at this SO answer for details.

Related

System.Web.Services.Protocols.SoapException: <web service> has not been properly Initialized

We are having the following setup:
A custom DLL (VB.Net) has a web reference to a custom web service (ASP.Net, let's call it WebService0).
This custom DLL is instantiated by custom .Net EXE program, which make use of the exposed functions in the DLL, which in turn make calls to said WebService0.
e.g. .Net EXE Program calls DLL function which calls WebService0.
This setup works fine.
Now, take this setup to another computer, but instead of calling the DLL from a custom program like above, it is being called from yet another web service layer (let's call this one WebService1). And to test this WebService1 there is another .Net EXE program (not the same one mentioned above).
e.g. .Net EXE Program calls WebService1, which calls custom DLL function, which in turn calls WebService0.
For some reason, this setup throws the following exception:
System.Web.Services.Protocols.SoapException: WebService0 has not been properly Initialized
What could be happening? The cause does not seem to be evident. We have checked everything to the best of our knowledge.
We have searched the internet and there is barely any information about it that we could find.
Any help is very much appreciated.
I guess that your WebService1 is the source of this exception, when calling the DLL. And you do NOT have configuration embeded into DLL itself.
You've propably forgot to configure your WebService1 web.config system.serviceModel section.
Take a look at your .Net EXE Program (the first one) and it's App.Config (or YourExeName.exe.config) to see what system.serviceModel section looks like. I expect at least section to be filled.
Do the same in your WebService1/web.config/system.serviceModel
In case my guess is wrong and you've done this already, show us your configuration.

How to class c# function in asp classic [duplicate]

After going through a number of different articles and not finding anything especially conclusive that takes me step-by-step through the process, I've come seeking help.
The Scenario
A client of mine is only proficient in development for ASP Classic. They have recently acquired an account for a site originally written in ASP.NET. They are rolling the site into something they can actively maintain, but the site originally included an image handler that took dynamically changing data regarding water levels and outputs an image containing a graphical representation of that data. The requirement is to develop a COM interop library that can be registered on the server and called with CreateObject to generate the same image's byte array for output using Response.BinaryWrite. The COM interop library must be registered at the remote site on a Windows 2000 Server, and I can't make any assumptions about their having access to regasm/gacutil to accomplish that task.
The Difficulty
I've built the class library by creating a Class Library project in Visual Studio 2010, choosing "COM Class" from the template, and inserting my code to generate a class with a single public method to return a byte array when given an integer (well, enumerator, but all the same). Unfortunately, even on my own development machine after building the library and registering (regasm) and caching the assembly (gacutil), I can't make a call through Classic ASP to instantiate the object, receiving instead an "ActiveX component can't create object" error. And, of course, at the server site, the DLL file can't be registered, the response being "Required module was not found."
Resources I've Used
I've already had a look through the following articles and haven't turned up the answers I need:
(Basic steps) Walkthrough: Creating COM Objects with Visual Basic
Build and Deploy a .NET COM Assembly
.NET COM+ Interop Component with Classic ASP
What I Need
Essentially what I need is a bit of hand-holding on a kind of step by step of what it's going to take to meet the requirements and create a COM+ interop module correctly in Visual Studio 2010. Creating the actual class object itself isn't terribly difficult.
However, none of the articles I've looked through really discuss project options or build procedures with Visual Studio 2010 or the .NET 4.0 Framework, nor have any of them really discussed if there are special considerations for deploying to older systems like Windows Server 2000 and the actual registration of the library on a system with only, say, regsvr32 on hand.
It should be fairly straightforward to get a basic .NET assembly exposed to COM - I've never tried the COM Class project template, so this is the way I've managed it in the past:
Create a new (bog standard) .NET class library using C# or VB. Define a COM interface (replace GUIDs with your own):
[ComVisible(true)]
[Guid("8999F93E-52F6-4E29-BA64-0ADC22A1FB11")]
public interface IComm
{
string GetMyGroups();
}
Now define a class that implements that interface (again, replace GUIDs with your own):
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[GuidAttribute("C5C5A1A8-9BFB-4CE5-B42C-4E6688F6840B")]
[ProgId("Test.Comm.1")]
public class Comm : IComm
{
public string GetMyGroups()
{
var comm = new CommunicatorAPI.MessengerClass();
var groups = comm.MyGroups as IMessengerGroups;
return string.Join(", ", groups.OfType<IMessengerGroup>().Select(g => g.Name).ToArray());
}
}
The Prog ID attribute on this class is what you will use to instantiate your component from ASP.
Strongly-name the assembly (Project properties -> "Signing" tab -> "Sign the assembly" -> Create a new strong name key file using the dropdown)
Now, build the assembly, and register using Regasm - if you don't wish to register in the GAC (which i'd recommend, as not GACing keeps the deployment simpler), be sure to use the -Codebase parameter (this just adds a reg entry that tells clients where to find the assembly) - e.g:
regasm ClassLibrary2.dll /codebase "S:\Testing\ClassLibrary2\ClassLibrary2\bin\Debug\ClassLibrary2.dll"
Now you should be able to instantiate the component, and call methods on it - for example (in javascript):
var a = new ActiveXObject("Test.Comm.1");
alert(a.GetMyGroups());
When it comes to deployment, the important work that Regasm and Regsvr32 do is to write various settings into the registry, so that clients can find the COM component (based on Prog ID, or COM Class ID). All you need to do is work out what COM settings are being written when you run Regasm on your local machine, and write these to the registry on the server. You can use ProcMon to monitor what gets written to the registry when Regasm is run.
Generally speaking, you can expect to see something like this written to the registry:
[HKEY_CLASSES_ROOT\Test.Comm.1]
#="ClassLibrary2.Comm"
[HKEY_CLASSES_ROOT\Test.Comm.1\CLSID]
#="{00585504-90C8-4760-A359-67CAF08FFED1}"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}]
#="ClassLibrary2.Comm"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\Implemented Categories]
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\InprocServer32]
#="mscoree.dll"
"ThreadingModel"="Both"
"Class"="ClassLibrary2.Comm"
"Assembly"="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf55d4e60653257a"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///S:/Testing/ClassLibrary2/ClassLibrary2/bin/Debug/ClassLibrary2.DLL"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\InprocServer32\1.0.0.0]
"Class"="ClassLibrary2.Comm"
"Assembly"="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf55d4e60653257a"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///S:/Testing/ClassLibrary2/ClassLibrary2/bin/Debug/ClassLibrary2.DLL"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\ProgId]
#="Test.Comm.1"
Hope this helps :)
I have a Classic ASP web site that uses a VB6 COM object. I wanted to create a new version of the COM object using .NET instead of VB6. This is how I did it (hope this helps). I include instructions for both C# and VB.NET.
[01]
Start Visual Studio 2015 (run as admin).
Create a new "Class Library" project.
Name it: "DotNetCom"
[02] C#
Add a new class, name it "HelloCOM".
Use the following code as starting template
( visit https://msdn.microsoft.com/en-us/library/c3fd4a20.aspx for more info )
using System.Runtime.InteropServices;
namespace DotNetCom
{
[Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
public interface HelloCOMInterface
{
[DispId(1)]
string Hello();
}
[Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface HelloCOMEvents
{
}
[Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(HelloCOMEvents))]
public class HelloCOM : HelloCOMInterface
{
public string Hello()
{
return "Hello there!";
}
}
}
[02] VB.NET
Add a new "COM class", name it "HelloCOM".
VB.NET creates the starting template.
Add the following function to the "HelloCOM" class.
Public Function Hello() As String
Return "Hello there!"
End Function
[03] C#
Open the project properties.
Go to "Application".
Click "Assembly Information...".
Check "Make assembly COM-Visible"
Go to "Build".
Select "Platform target: x86".
Check "Register COM for interop"
[03] VB.NET
Open "MyProject".
Go to "Compile".
Select "Target CPU: x86".
[04]
Build the "DotNetCom.dll".
[05]
Open a command prompt (run as admin).
Change directory to your dll.
cd DotNetComTest\DotNetComTest\TX7NGN.COM\bin\Debug
Run RegAsm /codebase.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm DotNetComTest.dll /codebase "C:\DotNetComTest\DotNetComTest\bin\Debug\DotNetComTest.dll"
[06]
Start Component Services.
Add a new COM+ application.
Name it: "DotNetCom".
Open the "DotNetCom" properties.
Go to the "Security Tab".
UNCHECK "Enforce access checks for this application".
[07]
Add a new component.
Select "DotNetComTest.tlb" (do NOT select "DotNetComTest.dll").
[08]
Use the COM object from the Classic ASP page.
<%
Dim HelloCOM
Set HelloCOM = Server.CreateObject("DotNetCom.HelloCOM")
Response.Write HelloCom.Hello
%>

.NET 3.5 - Stackframe's getmethod returns a property name prepended with unknown characters

ISSUE: StackFrame.GetMethod() returns a property name prepended with unknown characters (myProperty returned as __XY_myProperty).
Recently we have added a property to an existing class. This class is used in ASP.NET. Every property in this class calls a custom securitycheck function that uses stacktrace to get the method name of the callee to perform actions based on that name.
The issue is, StackFrame returns this newly added property name (myProperty) prepended with unknown characters (__XY_myProperty) during the runtime. This happens only on a production machine. We couldn't reproduce in any other machines that have similar settings.
Here is a sample of code:
// comments
public returntype myProperty
{
get
{
security.checkSecurity();
return returntype();
}
set
{
security.checkSecurity();
if (value == null)
{
Row["abc"] = anothervale;
}
else
{
Row["xyz"] = value;
}
}
}
// comment
StackFrame.GetMethod() call in security.checkSecurity() returns myProperty method name as: __XY_myProperty
(StackFrame.GetMethod() call not shown in the above example.)
What we tried is:
Cleared ASP.NET Caches
Compared .NET patches
Restarted the server
None of these resolved the issue.
Server Info:
Windows 2003
Runs on VMWare (Does JIT optimizes differently on VMWare?)
IIS 6
NET 3.5
ASP.NET project built in release mode
DLLs compiled in debug mode to make stacktrace behave properly
The answer is:
A profiler that installed on the machine was altering the MSIL code for code instrumentation.
Code instrumentation is the process of being able to modify the code as it is being given to the .NET runtime for execution. When the CLR loads a class and executes its method, the method's IL code is compiled to native instructions during the just-in-time (JIT) compilation process. The Profiling API provided as part of the CLR allows you to intercept this process. Before a method gets JIT-compiled, you can modify its IL code.
Solution: Uninstalled the profiler and everything works fine. It proved StackTrace is not dependable.

Building a COM interop library for ASP Classic using 4.0 framework and Visual Studio 2010

After going through a number of different articles and not finding anything especially conclusive that takes me step-by-step through the process, I've come seeking help.
The Scenario
A client of mine is only proficient in development for ASP Classic. They have recently acquired an account for a site originally written in ASP.NET. They are rolling the site into something they can actively maintain, but the site originally included an image handler that took dynamically changing data regarding water levels and outputs an image containing a graphical representation of that data. The requirement is to develop a COM interop library that can be registered on the server and called with CreateObject to generate the same image's byte array for output using Response.BinaryWrite. The COM interop library must be registered at the remote site on a Windows 2000 Server, and I can't make any assumptions about their having access to regasm/gacutil to accomplish that task.
The Difficulty
I've built the class library by creating a Class Library project in Visual Studio 2010, choosing "COM Class" from the template, and inserting my code to generate a class with a single public method to return a byte array when given an integer (well, enumerator, but all the same). Unfortunately, even on my own development machine after building the library and registering (regasm) and caching the assembly (gacutil), I can't make a call through Classic ASP to instantiate the object, receiving instead an "ActiveX component can't create object" error. And, of course, at the server site, the DLL file can't be registered, the response being "Required module was not found."
Resources I've Used
I've already had a look through the following articles and haven't turned up the answers I need:
(Basic steps) Walkthrough: Creating COM Objects with Visual Basic
Build and Deploy a .NET COM Assembly
.NET COM+ Interop Component with Classic ASP
What I Need
Essentially what I need is a bit of hand-holding on a kind of step by step of what it's going to take to meet the requirements and create a COM+ interop module correctly in Visual Studio 2010. Creating the actual class object itself isn't terribly difficult.
However, none of the articles I've looked through really discuss project options or build procedures with Visual Studio 2010 or the .NET 4.0 Framework, nor have any of them really discussed if there are special considerations for deploying to older systems like Windows Server 2000 and the actual registration of the library on a system with only, say, regsvr32 on hand.
It should be fairly straightforward to get a basic .NET assembly exposed to COM - I've never tried the COM Class project template, so this is the way I've managed it in the past:
Create a new (bog standard) .NET class library using C# or VB. Define a COM interface (replace GUIDs with your own):
[ComVisible(true)]
[Guid("8999F93E-52F6-4E29-BA64-0ADC22A1FB11")]
public interface IComm
{
string GetMyGroups();
}
Now define a class that implements that interface (again, replace GUIDs with your own):
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[GuidAttribute("C5C5A1A8-9BFB-4CE5-B42C-4E6688F6840B")]
[ProgId("Test.Comm.1")]
public class Comm : IComm
{
public string GetMyGroups()
{
var comm = new CommunicatorAPI.MessengerClass();
var groups = comm.MyGroups as IMessengerGroups;
return string.Join(", ", groups.OfType<IMessengerGroup>().Select(g => g.Name).ToArray());
}
}
The Prog ID attribute on this class is what you will use to instantiate your component from ASP.
Strongly-name the assembly (Project properties -> "Signing" tab -> "Sign the assembly" -> Create a new strong name key file using the dropdown)
Now, build the assembly, and register using Regasm - if you don't wish to register in the GAC (which i'd recommend, as not GACing keeps the deployment simpler), be sure to use the -Codebase parameter (this just adds a reg entry that tells clients where to find the assembly) - e.g:
regasm ClassLibrary2.dll /codebase "S:\Testing\ClassLibrary2\ClassLibrary2\bin\Debug\ClassLibrary2.dll"
Now you should be able to instantiate the component, and call methods on it - for example (in javascript):
var a = new ActiveXObject("Test.Comm.1");
alert(a.GetMyGroups());
When it comes to deployment, the important work that Regasm and Regsvr32 do is to write various settings into the registry, so that clients can find the COM component (based on Prog ID, or COM Class ID). All you need to do is work out what COM settings are being written when you run Regasm on your local machine, and write these to the registry on the server. You can use ProcMon to monitor what gets written to the registry when Regasm is run.
Generally speaking, you can expect to see something like this written to the registry:
[HKEY_CLASSES_ROOT\Test.Comm.1]
#="ClassLibrary2.Comm"
[HKEY_CLASSES_ROOT\Test.Comm.1\CLSID]
#="{00585504-90C8-4760-A359-67CAF08FFED1}"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}]
#="ClassLibrary2.Comm"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\Implemented Categories]
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\InprocServer32]
#="mscoree.dll"
"ThreadingModel"="Both"
"Class"="ClassLibrary2.Comm"
"Assembly"="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf55d4e60653257a"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///S:/Testing/ClassLibrary2/ClassLibrary2/bin/Debug/ClassLibrary2.DLL"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\InprocServer32\1.0.0.0]
"Class"="ClassLibrary2.Comm"
"Assembly"="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf55d4e60653257a"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///S:/Testing/ClassLibrary2/ClassLibrary2/bin/Debug/ClassLibrary2.DLL"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00585504-90C8-4760-A359-67CAF08FFED1}\ProgId]
#="Test.Comm.1"
Hope this helps :)
I have a Classic ASP web site that uses a VB6 COM object. I wanted to create a new version of the COM object using .NET instead of VB6. This is how I did it (hope this helps). I include instructions for both C# and VB.NET.
[01]
Start Visual Studio 2015 (run as admin).
Create a new "Class Library" project.
Name it: "DotNetCom"
[02] C#
Add a new class, name it "HelloCOM".
Use the following code as starting template
( visit https://msdn.microsoft.com/en-us/library/c3fd4a20.aspx for more info )
using System.Runtime.InteropServices;
namespace DotNetCom
{
[Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
public interface HelloCOMInterface
{
[DispId(1)]
string Hello();
}
[Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface HelloCOMEvents
{
}
[Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(HelloCOMEvents))]
public class HelloCOM : HelloCOMInterface
{
public string Hello()
{
return "Hello there!";
}
}
}
[02] VB.NET
Add a new "COM class", name it "HelloCOM".
VB.NET creates the starting template.
Add the following function to the "HelloCOM" class.
Public Function Hello() As String
Return "Hello there!"
End Function
[03] C#
Open the project properties.
Go to "Application".
Click "Assembly Information...".
Check "Make assembly COM-Visible"
Go to "Build".
Select "Platform target: x86".
Check "Register COM for interop"
[03] VB.NET
Open "MyProject".
Go to "Compile".
Select "Target CPU: x86".
[04]
Build the "DotNetCom.dll".
[05]
Open a command prompt (run as admin).
Change directory to your dll.
cd DotNetComTest\DotNetComTest\TX7NGN.COM\bin\Debug
Run RegAsm /codebase.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm DotNetComTest.dll /codebase "C:\DotNetComTest\DotNetComTest\bin\Debug\DotNetComTest.dll"
[06]
Start Component Services.
Add a new COM+ application.
Name it: "DotNetCom".
Open the "DotNetCom" properties.
Go to the "Security Tab".
UNCHECK "Enforce access checks for this application".
[07]
Add a new component.
Select "DotNetComTest.tlb" (do NOT select "DotNetComTest.dll").
[08]
Use the COM object from the Classic ASP page.
<%
Dim HelloCOM
Set HelloCOM = Server.CreateObject("DotNetCom.HelloCOM")
Response.Write HelloCom.Hello
%>

Class will compile for Tests/Console but not in Asp.net application

I have a simple interface:
public interface IVisitorsLogController
{
List<VisitorsLog> GetVisitorsLog();
int GetUniqueSubscribersCount();
int GetVisitorsCount();
string GetVisitorsSummary();
}
the class VisitorsLogController implements this interface.
From a console application or a TestFixture - no problem - the console/test fixture compile perfectly.
However, from an Asp.Net web site (not application) in the same solution with this code in the code behind
private IVisitorsLogController ctl;
protected int GetUniqueMembersCount()
{
ctl = new VisitorsLogController();
return ctl.GetUniqueSubscribersCount();
}
the compiler throws this exception:
Error 1 'WebSiteBusinessRules.Interfaces.IVisitorsLogController'
does not contain a definition for
'GetUniqueSubscribersCount' and no
extension method
'GetUniqueSubscribersCount' accepting
a first argument of type
'WebSiteBusinessRules.Interfaces.IVisitorsLogController'
could be found (are you missing a
using directive or an assembly
reference?)
yet for this code in the same file:
protected static int GetVisitorsCount()
{
return VisitorsLogController.Instance.GetVisitorsCount(DateTime.Today);
}
the compiler compiles these lines without complaining. In fact if I add anything new to the Interface the compiler now complains when trying to compile the asp.net page.
It can't be a missing using directive or assembly reference otherwise both methods would fail.
This is driving me nuts!
Any thoughts please?
Thanks,
Jeremy
Out of interest, can you compile the following line:
ctl = VisitorsLogController.Instance;
? I'm just wondering if somehow you've got two interfaces named the same thing.
What does Intellisense prompt you with when you type ctl. and press Ctrl-Space?
It would seem the other important bit of code would be VisitorsLogController, wouldn't it? It looks like VisitorsLogController is implementing a different IVistorsLogController interface.
Right clicking and GoTo Definition should clear things up, I think.
I would start by checking the namespaces on each of the files involved and make sure that you don't have a conflict or a namespace that you are not expecting.
The solution contains the web site and three class projects (Data Layer, Service Layer and Core Services). They are added as references to the web site as Projects.
I had compiled the solution at one point for Release - published the site, and then changed the config to Debug.
Evidently what had happened was that the Release dll's in the /bin file of the website were not being overwritten by the new Debug dll's. I manually deleted all the files in the /bin directory, and lo and behold - everything compiled perfectly.
So Mark and John - you were both spot on - I effectively did have two interfaces named the same thing.
Thanks very much for your help - if you hadn't given me these pointers I would never have finally worked it out.

Resources