views:

288

answers:

4

I'm rewriting an old VBSCript WSC component into a nicer C# COM Component.

For a horrid reason the old component in one place is passed the Server Context, IServer by using

Set objCurr = CreateObject("MTxAS.AppServer.1")
Set objCurrObjCont = objCurr.GetObjectContext()
Set component.servercontext = objCurrObjCont("Server")

this is then used to do a standard Server.MapPath("/somelocation")

However I'm stumped upon what to do in the .Net COM Component, System.Web.HttpContext.Current.MapPath() doesn't work as expected as there is no Web Context.

I tried passing the context from Classic ASP into the COM Component but I'm not sure which reference to include so I can invoke the correct member, Microsoft.Active X Data Objects 2.7 seems a common one, but this only includes Recordsets etc, nothing for the C++ IServer interface so it comes our just as a COM OBJECT.

Does anyone know of a way to do this / a work around? At this rate I'm thinking I may have to change the behaviour of the component

A: 

Why not pass in the full path to "/somelocation" to your C# COM component? This will help you get rid of some ugly dependencies.


UPDATE: You may want to try HostingEnvironment.MapPath. You need to add a reference to System.Web before using it.

Jakob Christensen
this is what I wanted to do, infact I do for the path to an xml file it uses to start up however it then finds a virtual path in this XML file that it needs to then map within the component, I know it's dirty but at the moment I'm tied to only changing this component
MJJames
Did you try HostingEnvironment.MapPath?
Jakob Christensen
Unfortunately HostingEnvironment.MapPath doesn't work
MJJames
+2  A: 

I think indeed changing the behaviour is the best option here... wel... not exactly the behaviour, but the interface of the COM object... Instead of passing in the server context, just pass in the relevant information needed for the method.

fretje
This is probably the best option, following The Law of Demeter - http://en.wikipedia.org/wiki/Law_of_Demeter
Nate Bross
A: 

You may be able to use reflection to invoke the method you need. - http://www.csharphelp.com/archives/archive200.html

Nate Bross
+4  A: 

Add to your C# project an interop for ASP.dll (you will find it in the \system32\inetsrv folder.

Add a public method to the class that gets instantiated by ASP:-

 ASPTypeLibrary.ScriptingContext context;
 public void OnStartPage(ASPTypeLibrary.ScriptingContext sc)
 {
     context = sc;
 }

Now when you need a MapPath use:-

 context.Server.MapPath("...");

Note context gives you access to the Request, Response and Session in addition to Server. The OnStartPage is a pre-COM+ hack that ASP used and still works even in the latest versions. ASP performs the COM equivalent of reflection (examining the COM classes type library info) to determine if a public OnStartPage method is available, if so it calls it passing the ScriptingContext object.

There is no .NET HttpContext available, the request would have had to have been handled by .NET in the first place for that to exist. A HttpContext cannot be created on a thread "after the fact" as it were. Hence if your component needs to interact with the Http conversation it will have to do so via the ASP context object since ASP is the host that is actually handling the request.

AnthonyWJones
Man if that work then it genius! Good depth of Knowledge Anthony, hats off to you.
Pete Duncanson