Server.MapPath in a COM Component

2019-04-09 11:56发布

问题:

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

回答1:

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.



回答2:

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.



回答3:

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.