By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,949 Members | 884 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,949 IT Pros & Developers. It's quick & easy.

Serailize RCW class OR IPersistStream call to RCW class question

P: n/a
Hi.

I have a RCW class that was generated by the VS.NET2003 IDE when I added a
COM dll reference to my project. This all works fine when I call methods on
it. My initial problem is that in ASP.NET I would like to add this to the
Session object whilst using SQLServer as the session storage. Unfortunately,
as this required the RCW class to be serializable, this won't work, and
throws an exception saying you can't Serialize the Session state if it
contains objects that are MarshalByRef and the session state mode is
SQLServer.

So question 1 - Is there an easy way to make an RCW class serializable? (I'm
expecting this to be "No", but if you don't ask you don't get)

Question 2 - My COM dll is capable of storing its own state, via its
implementation of IPersistStream. After a lot of Googling I've added C#
definitions of IPersist and IPersistStream. If I have a class AAA which
contains an instance of MyLib::IRCWClass which is marked as
NonSerializable, then I've set AAA to implement ISerializable, and in
GetObjectData() I have

MemoryStream memstream = new MemoryStream();
ComStream cstream = new ComStream(memstream);
IPersistStream pStream = (IPersistStream)m_RCWClass;

if ( pStream != null )
pStream.Save( cstream, false );
else
Trace.WriteLine( "No IPersistStream" );

This throws the same exception when it calls Save. However if I change the
third line to

IPersistStream pStream = m_RCWClass as IPersistStream;

This also throws the same exception. Is there any way to gain access to the
IPersistStream methods, and then serialize the contents of my stream?

Question 3 - As an alternative approach, I've tried to get the bytes out of
the IPersistStream another way, with a view to storing this byte array
separately in the Session object. A first attempt is

IPersistStream p = m_AAAClass.RCWClass as IPersistStream;

if ( p != null )
{
System.IO.MemoryStream memstream = new System.IO.MemoryStream();
ComStream cstream = new ComStream(memstream);
if ( p != null )
{
p.Save( cstream, false );
System.IO.MemoryStream mem = cstream.stream as
System.IO.MemoryStream;
return mem.GetBuffer();
}
else
return null;
}
return null;

This time the pointer to IPersistStream is null the first time, but after
that always throws a COMException with the message "The server threw an
exception". Am I barking up the wrong tree?

Fundamentally wanting to store an RCW class in the Session object doesn't
seem to be a strange thing to want to do, but after Googling myself into a
frenzy, it seems that very few people have asked about it. Those that have
have been told to set the sesseion state to InProc, but this isn't really an
option, as this means you can't run on a web farm. Any ideas please?

Cheers,

Chris

Nov 19 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Well, when you think of what RCW stands for, its simply a wrapper for
another class. In this case, its a wrapper to a com instance which may or
may not me serializable (remember that could be looking at a c++ 6.0 on the
other side of a wrapper.

Secondly, the COM+ paradigm focuses on a service oriented architecture
where your COM+ components are stateless, or maintain a transient state. So
if you have a COM+ class that does need to maintain sone sort of state, then
your might need to re-architect your solution.

Now, there is no reason that a serializable class can not call a COM+
instance to perform some kind of action. That might be something that can
help you out. Also you can pass serializable classes to COM+ components by
reference.

You'll really want to take a lok at your state management strategy as a
whole and see if there os some way of bringing it down to a single point.
In the traditional approach to web applications, this has meant that state
was always managed through the use of relational databases (e.g. the famous
Shopping cart). I'm not recommenting this as a target architecture, but it
you can take a look at your user state from the standpoint of creating a
single "thing" database, class, session object, etc, that represents your
state, it might clear things up

"Chris Puncher" <ch*******************@NOdocumationSPAM.co.uk> wrote in
message news:eA**************@TK2MSFTNGP11.phx.gbl...
Hi.

I have a RCW class that was generated by the VS.NET2003 IDE when I added a
COM dll reference to my project. This all works fine when I call methods on it. My initial problem is that in ASP.NET I would like to add this to the
Session object whilst using SQLServer as the session storage. Unfortunately, as this required the RCW class to be serializable, this won't work, and
throws an exception saying you can't Serialize the Session state if it
contains objects that are MarshalByRef and the session state mode is
SQLServer.

So question 1 - Is there an easy way to make an RCW class serializable? (I'm expecting this to be "No", but if you don't ask you don't get)

Question 2 - My COM dll is capable of storing its own state, via its
implementation of IPersistStream. After a lot of Googling I've added C#
definitions of IPersist and IPersistStream. If I have a class AAA which
contains an instance of MyLib::IRCWClass which is marked as
NonSerializable, then I've set AAA to implement ISerializable, and in
GetObjectData() I have

MemoryStream memstream = new MemoryStream();
ComStream cstream = new ComStream(memstream);
IPersistStream pStream = (IPersistStream)m_RCWClass;

if ( pStream != null )
pStream.Save( cstream, false );
else
Trace.WriteLine( "No IPersistStream" );

This throws the same exception when it calls Save. However if I change the
third line to

IPersistStream pStream = m_RCWClass as IPersistStream;

This also throws the same exception. Is there any way to gain access to the IPersistStream methods, and then serialize the contents of my stream?

Question 3 - As an alternative approach, I've tried to get the bytes out of the IPersistStream another way, with a view to storing this byte array
separately in the Session object. A first attempt is

IPersistStream p = m_AAAClass.RCWClass as IPersistStream;

if ( p != null )
{
System.IO.MemoryStream memstream = new System.IO.MemoryStream();
ComStream cstream = new ComStream(memstream);
if ( p != null )
{
p.Save( cstream, false );
System.IO.MemoryStream mem = cstream.stream as
System.IO.MemoryStream;
return mem.GetBuffer();
}
else
return null;
}
return null;

This time the pointer to IPersistStream is null the first time, but after
that always throws a COMException with the message "The server threw an
exception". Am I barking up the wrong tree?

Fundamentally wanting to store an RCW class in the Session object doesn't
seem to be a strange thing to want to do, but after Googling myself into a
frenzy, it seems that very few people have asked about it. Those that have
have been told to set the sesseion state to InProc, but this isn't really an option, as this means you can't run on a web farm. Any ideas please?

Cheers,

Chris

Nov 19 '05 #2

P: n/a
David,

Thanks for your reply. The posistion I'm in is that the company I work for
has a successful web product (ASP/C++ ATL COM). This is gradually being
moved to ASP.NET, but in the process many of the underlying COM components
will still be used, albeit with thin C# .NET wrappers on top. The COM
component that I'm having problems with is our existing session state
object, hence its ability to stream itself (where in the old product it is
written to a SQLServer database). This object is then deserialised and
passed into many of the other COM components which are required to perform
business functionality.

So what I am trying to do is put the RCW class instance for the existing
session state object into ASP.NET's Session object, and hence to SQLServer.
Failing this then if I can get at the byte stream that represents the old
session state object, I'll be happy to stick that in Session.

I hope this clears up my question a bit.

Cheers,

Chris

"David Jessee" <dj*****@houston.rr.com> wrote in message
news:us**************@TK2MSFTNGP11.phx.gbl...
Well, when you think of what RCW stands for, its simply a wrapper for
another class. In this case, its a wrapper to a com instance which may or
may not me serializable (remember that could be looking at a c++ 6.0 on the other side of a wrapper.

Secondly, the COM+ paradigm focuses on a service oriented architecture
where your COM+ components are stateless, or maintain a transient state. So if you have a COM+ class that does need to maintain sone sort of state, then your might need to re-architect your solution.

Now, there is no reason that a serializable class can not call a COM+
instance to perform some kind of action. That might be something that can
help you out. Also you can pass serializable classes to COM+ components by reference.

You'll really want to take a lok at your state management strategy as a
whole and see if there os some way of bringing it down to a single point.
In the traditional approach to web applications, this has meant that state
was always managed through the use of relational databases (e.g. the famous Shopping cart). I'm not recommenting this as a target architecture, but it
you can take a look at your user state from the standpoint of creating a
single "thing" database, class, session object, etc, that represents your
state, it might clear things up

"Chris Puncher" <ch*******************@NOdocumationSPAM.co.uk> wrote in
message news:eA**************@TK2MSFTNGP11.phx.gbl...
Hi.

I have a RCW class that was generated by the VS.NET2003 IDE when I added a COM dll reference to my project. This all works fine when I call methods on
it. My initial problem is that in ASP.NET I would like to add this to the Session object whilst using SQLServer as the session storage.

Unfortunately,
as this required the RCW class to be serializable, this won't work, and
throws an exception saying you can't Serialize the Session state if it
contains objects that are MarshalByRef and the session state mode is
SQLServer.

So question 1 - Is there an easy way to make an RCW class serializable?

(I'm
expecting this to be "No", but if you don't ask you don't get)

Question 2 - My COM dll is capable of storing its own state, via its
implementation of IPersistStream. After a lot of Googling I've added C#
definitions of IPersist and IPersistStream. If I have a class AAA which
contains an instance of MyLib::IRCWClass which is marked as
NonSerializable, then I've set AAA to implement ISerializable, and in
GetObjectData() I have

MemoryStream memstream = new MemoryStream();
ComStream cstream = new ComStream(memstream);
IPersistStream pStream = (IPersistStream)m_RCWClass;

if ( pStream != null )
pStream.Save( cstream, false );
else
Trace.WriteLine( "No IPersistStream" );

This throws the same exception when it calls Save. However if I change the third line to

IPersistStream pStream = m_RCWClass as IPersistStream;

This also throws the same exception. Is there any way to gain access to

the
IPersistStream methods, and then serialize the contents of my stream?

Question 3 - As an alternative approach, I've tried to get the bytes out

of
the IPersistStream another way, with a view to storing this byte array
separately in the Session object. A first attempt is

IPersistStream p = m_AAAClass.RCWClass as IPersistStream;

if ( p != null )
{
System.IO.MemoryStream memstream = new System.IO.MemoryStream();
ComStream cstream = new ComStream(memstream);
if ( p != null )
{
p.Save( cstream, false );
System.IO.MemoryStream mem = cstream.stream as
System.IO.MemoryStream;
return mem.GetBuffer();
}
else
return null;
}
return null;

This time the pointer to IPersistStream is null the first time, but after that always throws a COMException with the message "The server threw an
exception". Am I barking up the wrong tree?

Fundamentally wanting to store an RCW class in the Session object doesn't seem to be a strange thing to want to do, but after Googling myself into a frenzy, it seems that very few people have asked about it. Those that have have been told to set the sesseion state to InProc, but this isn't

really an
option, as this means you can't run on a web farm. Any ideas please?

Cheers,

Chris


Nov 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.