Handling System._ComObject -- using CCW

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Varun Singal

    Handling System._ComObject -- using CCW

    Hi

    I am calling .NET components from my Classical ASPs.
    For this I strong named my assemblies, then registered them in the resistry
    ( using RegAsm), and put them in GAC (using GacUtil) .
    Everything worked fine and my ASPs were able to call and use them.

    The problem comes when my ASP code assigns an ASP object variable to a
    property of a class in the assembly like:
    oDotNetObject(" Name") = Request("Name")
    ( where oDotNetObject is a class in my registered assembly )

    The COM Callable Wrapper sends it as System._ComObje ct to .NET Runtime which
    then throws exception as nothing is allowed on System._ComObje ct. On the
    other hand, passing it as Variant solves the problem.
    Dim varName = Request("Name")
    oDotNetObject(" Name") = varName

    But this would require a significant change in my ASP pages. I want to
    modify only my .NET components. Is there any way I can use this
    System._ComObje ct in my managed code or any way I can make CCW to handle it.
    I was trying to use System.Runtime. InteropServices .Marshal namespace to use
    the System._ComObje ct I have not been able to do it.

    Thanks in anticipation
    Varun


  • Varun Singal

    #2
    Re: Handling System._ComObje ct -- using CCW

    Thanks Oisin

    But here my problem is that I am working on a huge application and I cant
    change this usage in ASP files.
    So I have to find a solution in .Net component -- as you said -- i will have
    to marshal a com object
    Any ideas about that!

    Thanks
    Varun

    "Oisin Grehan" <oising@nospam. iol.ie.> wrote in message
    news:OFHJDiJRDH A.3664@tk2msftn gp13.phx.gbl...[color=blue]
    > By assigning Request("Name") to the property, you are using a bad habit[/color]
    most[color=blue]
    > of us have by relying on default properties. Take a look at this:
    >
    > <%
    > Dim strName
    > strName = Request("Name")
    > %>
    >
    > The ASP engine will assigning the default property (which happens to be
    > "Item") to the variable and everything will be fine. However, when you[/color]
    use:[color=blue]
    >
    > oDotNetObject(" Name") = Request("Name")
    >
    > You are relying on the DotNet class to retrieve the default property from
    > the COM object "Request". If you use:
    >
    > oDotNetObject(" Name") = Request("Name") .Item
    >
    > Everything should be mostl likely be fine as you are not longer[/color]
    marshalling[color=blue]
    > a COM object, but rather a simple string.
    >
    > Hope this helps,
    >
    > - Oisin
    >
    >
    >
    >
    >
    > "Varun Singal" <varun.singal@i nduslogic.com> wrote in message
    > news:u$7ErPJRDH A.1624@tk2msftn gp13.phx.gbl...[color=green]
    > > Hi
    > >
    > > I am calling .NET components from my Classical ASPs.
    > > For this I strong named my assemblies, then registered them in the[/color]
    > resistry[color=green]
    > > ( using RegAsm), and put them in GAC (using GacUtil) .
    > > Everything worked fine and my ASPs were able to call and use them.
    > >
    > > The problem comes when my ASP code assigns an ASP object variable to a
    > > property of a class in the assembly like:
    > > oDotNetObject(" Name") = Request("Name")
    > > ( where oDotNetObject is a class in my registered assembly )
    > >
    > > The COM Callable Wrapper sends it as System._ComObje ct to .NET Runtime[/color]
    > which[color=green]
    > > then throws exception as nothing is allowed on System._ComObje ct. On the
    > > other hand, passing it as Variant solves the problem.
    > > Dim varName = Request("Name")
    > > oDotNetObject(" Name") = varName
    > >
    > > But this would require a significant change in my ASP pages. I want to
    > > modify only my .NET components. Is there any way I can use this
    > > System._ComObje ct in my managed code or any way I can make CCW to handle[/color]
    > it.[color=green]
    > > I was trying to use System.Runtime. InteropServices .Marshal namespace to[/color]
    > use[color=green]
    > > the System._ComObje ct I have not been able to do it.
    > >
    > > Thanks in anticipation
    > > Varun
    > >
    > >[/color]
    >
    >[/color]


    Comment

    • Oisin Grehan

      #3
      Re: Handling System._ComObje ct -- using CCW

      Varun, surely it is more work to facilitate this than to spend a while with
      global find/replace with regex on those ASP files? Marshalling COM objects
      instead of strings is hugely inefficient, incredibly lazy as well as just
      plain wrong. But, if you really are a masochist (or an assembly
      programmer -- same thing), keep reading:

      First of all, I hope you're comfortable with COM interop, IDL, type
      libraries and other such nasties. I'm not an interop specialist nor a COM
      guru by any means, so I can only try to direct you. Right, since you're
      passing in a System._ComObje ct object, I believe you'll need to use the
      MarshalAs attribute to tell .NET that you're expecting
      UnmanagedType.I Dispatch. "Request" is an IDispatch object. If we inspect the
      IDL with OleView (tool included with VS) by pointing it at the ASP type
      library available at C:\Program Files\Microsoft Visual
      Studio\Common\I DE\IDE98\asp.tl b assuming you've got Vstudio 6.0 installed in
      the default location, you can see the following info (trimmed down for
      brevity) for IRequest:

      [odl, uuid(D97A6DA0-A861-11CF-93AE-00A0C90C2BD8), hidden, dual,
      oleautomation]
      interface IRequest : IDispatch {
      [id(00000000), propget]
      HRESULT Item([in] BSTR bstrVar, [out, retval] IDispatch** ppObjReturn);

      HRESULT QueryString([out, retval] IRequestDiction ary** ppDictReturn);
      HRESULT Form([out, retval] IRequestDiction ary** ppDictReturn);
      };

      You'll see that Item is the default property (IDL id of 0), it returns an
      IDispatch interface, most likely this one in your case:

      [odl, uuid(D97A6DA0-A85F-11DF-83AE-00A0C90C2BD8), helpstring("Dic tionary for
      Request collections"), hidden, dual, oleautomation]
      interface IRequestDiction ary : IDispatch {
      [id(00000000), propget]
      HRESULT Item([in, optional] VARIANT Var, [out, retval] VARIANT*
      pVariantReturn) ;
      };

      Again, you can see the default property for the IRequestDiction ary is Item
      also, which returns a variant. This is the variant you need to get your
      grubby hands on. All the information you'll need to imbibe and understand is
      on MSDN. A good place to start is to look up the MarshalAs attribute and
      pay attention to the UnmanagedType enumeration. There's some good example
      code there.

      Now, if this hasn't put you off, you plainly have access to the ASP
      source -- is it really that huge a task to change it? Open all ASP pages in
      VS.NET, use Find/Replace with Regular Expressions. Replace .*
      \=\s?Request\(" {.*}\"\) with = Request("\1").I tem. Bingo, assuming that
      Regex expression out of my head is correct. If you have the time, sit back
      and learn COM interop. If that looks like too steep a hill to climb, change
      the ASP pages, or better yet, learn Regular Expressions. It'll be the best
      hour you've spend in front of the computer today and it will pay you back
      many times over.

      Hope this helps,

      - Oisin







      "Varun Singal" <varun.singal@i nduslogic.com> wrote in message
      news:eNzcCRKRDH A.3768@tk2msftn gp13.phx.gbl...[color=blue]
      > Thanks Oisin
      >
      > But here my problem is that I am working on a huge application and I cant
      > change this usage in ASP files.
      > So I have to find a solution in .Net component -- as you said -- i will[/color]
      have[color=blue]
      > to marshal a com object
      > Any ideas about that!
      >
      > Thanks
      > Varun
      >
      > "Oisin Grehan" <oising@nospam. iol.ie.> wrote in message
      > news:OFHJDiJRDH A.3664@tk2msftn gp13.phx.gbl...[color=green]
      > > By assigning Request("Name") to the property, you are using a bad habit[/color]
      > most[color=green]
      > > of us have by relying on default properties. Take a look at this:
      > >
      > > <%
      > > Dim strName
      > > strName = Request("Name")
      > > %>
      > >
      > > The ASP engine will assigning the default property (which happens to be
      > > "Item") to the variable and everything will be fine. However, when you[/color]
      > use:[color=green]
      > >
      > > oDotNetObject(" Name") = Request("Name")
      > >
      > > You are relying on the DotNet class to retrieve the default property[/color][/color]
      from[color=blue][color=green]
      > > the COM object "Request". If you use:
      > >
      > > oDotNetObject(" Name") = Request("Name") .Item
      > >
      > > Everything should be mostl likely be fine as you are not longer[/color]
      > marshalling[color=green]
      > > a COM object, but rather a simple string.
      > >
      > > Hope this helps,
      > >
      > > - Oisin
      > >
      > >
      > >
      > >
      > >
      > > "Varun Singal" <varun.singal@i nduslogic.com> wrote in message
      > > news:u$7ErPJRDH A.1624@tk2msftn gp13.phx.gbl...[color=darkred]
      > > > Hi
      > > >
      > > > I am calling .NET components from my Classical ASPs.
      > > > For this I strong named my assemblies, then registered them in the[/color]
      > > resistry[color=darkred]
      > > > ( using RegAsm), and put them in GAC (using GacUtil) .
      > > > Everything worked fine and my ASPs were able to call and use them.
      > > >
      > > > The problem comes when my ASP code assigns an ASP object variable to a
      > > > property of a class in the assembly like:
      > > > oDotNetObject(" Name") = Request("Name")
      > > > ( where oDotNetObject is a class in my registered assembly )
      > > >
      > > > The COM Callable Wrapper sends it as System._ComObje ct to .NET Runtime[/color]
      > > which[color=darkred]
      > > > then throws exception as nothing is allowed on System._ComObje ct. On[/color][/color][/color]
      the[color=blue][color=green][color=darkred]
      > > > other hand, passing it as Variant solves the problem.
      > > > Dim varName = Request("Name")
      > > > oDotNetObject(" Name") = varName
      > > >
      > > > But this would require a significant change in my ASP pages. I want to
      > > > modify only my .NET components. Is there any way I can use this
      > > > System._ComObje ct in my managed code or any way I can make CCW to[/color][/color][/color]
      handle[color=blue][color=green]
      > > it.[color=darkred]
      > > > I was trying to use System.Runtime. InteropServices .Marshal namespace[/color][/color][/color]
      to[color=blue][color=green]
      > > use[color=darkred]
      > > > the System._ComObje ct I have not been able to do it.
      > > >
      > > > Thanks in anticipation
      > > > Varun
      > > >
      > > >[/color]
      > >
      > >[/color]
      >
      >[/color]


      Comment

      Working...