Serialization Question (Advanced)

S

Scott Simes

Hello:

I am trying to serialize only certain properties (not the methods) of my
class, say class A. I understand that I can use the [NonSerialized]
attribute on the methods and perhaps specific properties I do not wish to
serialize. It is important to know that the serialization, in my case, will
be written by the framework to the ViewState in an ASP.NET app--so it is
critical to keep the serialization content as "light" as possible (that's
why I do not want to serialize methods or non-essential properties). I
understand that I can implement the ISerializable interface, but I am trying
to understand whether there is a way to use the [Serializable] and
[Nonserialized] attributed to achieve the same result (it's less a matter of
laziness than it is wanting the ViewState 'framework' to handle the
serialization for me).

To save space in this message, please assume I have marked class A as
[Serializable] and all functions and certain properties as
[NonSerialized]...

In my code-behind module I create an object instance called objectA:

A objectA = new A();

I then set the properties of objectA:

objectA.valueOne = 1;
objectA.valueTwo = 2;
(etc.)

I then set ViewState["ObjectA"] = objectA. In the postback, I want to
deserialize ViewState["ObjectA"] into an object instance of class A.

Here are my questions:

(1) Is it possible to simply cast the return value to class A as so that it
contains all the methods and non-serialized properties of the class A
definition?

A a = (A)ViewState["ObjectA"];

(2) If (1) is not correct, what is the least amount of code I can use to
create a new object instance of class A that "inherits" all the serialized
information from ViewState["ObjectA"]?

I thought about creating another class, class B. Class B would be fully
serializable, and this is the class I would persist in the ViewState. I
could then create a version of class A that inherits from class B. The
reason I did not take this approach is that I do not know how to take an obj
ect instance of class B and force an object instance of class A to "inherit"
the values already contained in an object-instance of class B (without
overloading the "=" sign or implementing other more code-intensive
solutions).

I also thought about creating a struct, and persisting the struct through
serialization. This struct could be a public property of class A. But if I
do this, there are some downsides because the purpose of the struct would be
simply to support serialization, and serialization seems to be supported by
classes and the serialization attributes ([Serialized] and
[NonSerializable]) without the need for structs.

Any ideas on this would be greatly appreciated.
 
N

Nicholas Paldino [.NET/C# MVP]

Scott,

I think that you have a few things confused. Properties and methods are
not serialized, as they can not be. They do not store state beyond their
calls (remember, properties are just methods with a different
representation). When you use serialization (not XML serialization, but
true serialization with an implementation of IFormatter), it serializes the
fields of the class, storing those values.

You are right, you can use the NonSerialized attribute on fields to
indicate that you don't want those fields serialized. Also, you can
implement the ISerializable interface yourself.

Onto your questions:
(1) Is it possible to simply cast the return value to class A as so that it
contains all the methods and non-serialized properties of the class A
definition?

A a = (A)ViewState["ObjectA"];

No. You will have to take the viewstate and then translate that from a
string, to bytes (possibly, if it is binary formatted), and then call
Deserialize on the formatter. At that point, you can cast the return value
from Deserialize to your type.
(2) If (1) is not correct, what is the least amount of code I can use to
create a new object instance of class A that "inherits" all the serialized
information from ViewState["ObjectA"]?

The least amount of code would be creating the formatter, calling the
deserialize method (possibly changing the view state returned to bytes, in
the case of a binary formatter), and then casting the object back.

You might want to consider using the session state to store your values.
Viewstate is a nice feature, but depending on the data you want to store,
might be overkill.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
I thought about creating another class, class B. Class B would be fully
serializable, and this is the class I would persist in the ViewState. I
could then create a version of class A that inherits from class B. The
reason I did not take this approach is that I do not know how to take an obj
ect instance of class B and force an object instance of class A to "inherit"
the values already contained in an object-instance of class B (without
overloading the "=" sign or implementing other more code-intensive
solutions).

I also thought about creating a struct, and persisting the struct through
serialization. This struct could be a public property of class A. But if I
do this, there are some downsides because the purpose of the struct would be
simply to support serialization, and serialization seems to be supported by
classes and the serialization attributes ([Serialized] and
[NonSerializable]) without the need for structs.

Any ideas on this would be greatly appreciated.
 
S

Scott Simes

Thank you for your reply.

OK--I may have been confused the methods are serialized, but the reason I
had concluded this is that I encountered this error in my code-behind
module:

"The type {ClassA} must be marked as Serializable or have a TypeConverter
other than ReferenceConverter to be put in viewstate."

I then examined the class definition and realized that one of the methods in
that class was using another object that was not marked as [Serialized]. So
I marked that class as [Serialized], and then it worked (I no longer
recieved the above error). Thus, the class was not able to be serialized
until I fixed the way in which of its methods worked. Why would the
serialization process look at any of the methods when it is simply trying to
serialize the fields with the values they contain immediate prior to
serialization?

Also, I don't know how or why (based on your reply), but I was in fact able
to get many of my objects to be serialized to the ViewState with no
formatters and no explicit deserialization calls. In fact, my code (which
uses a simpler class) is successful doing this:

ViewState["objectA"] = (A)objectA;

And then later doing this:

object x = ViewState["objectA"];
((A)x).valueOne = 1;

This works successfully.

Session variables are not an option for me in this case because I require
scalability (that is, I plan to have several load-balanced web servers) and
I do not wish to use server resources to persist these particular
page-to-page values.

Regards,
Scott

Nicholas Paldino said:
Scott,

I think that you have a few things confused. Properties and methods are
not serialized, as they can not be. They do not store state beyond their
calls (remember, properties are just methods with a different
representation). When you use serialization (not XML serialization, but
true serialization with an implementation of IFormatter), it serializes the
fields of the class, storing those values.

You are right, you can use the NonSerialized attribute on fields to
indicate that you don't want those fields serialized. Also, you can
implement the ISerializable interface yourself.

Onto your questions:
(1) Is it possible to simply cast the return value to class A as so that it
contains all the methods and non-serialized properties of the class A
definition?

A a = (A)ViewState["ObjectA"];

No. You will have to take the viewstate and then translate that from a
string, to bytes (possibly, if it is binary formatted), and then call
Deserialize on the formatter. At that point, you can cast the return value
from Deserialize to your type.
(2) If (1) is not correct, what is the least amount of code I can use to
create a new object instance of class A that "inherits" all the serialized
information from ViewState["ObjectA"]?

The least amount of code would be creating the formatter, calling the
deserialize method (possibly changing the view state returned to bytes, in
the case of a binary formatter), and then casting the object back.

You might want to consider using the session state to store your values.
Viewstate is a nice feature, but depending on the data you want to store,
might be overkill.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
I thought about creating another class, class B. Class B would be fully
serializable, and this is the class I would persist in the ViewState. I
could then create a version of class A that inherits from class B. The
reason I did not take this approach is that I do not know how to take an obj
ect instance of class B and force an object instance of class A to "inherit"
the values already contained in an object-instance of class B (without
overloading the "=" sign or implementing other more code-intensive
solutions).

I also thought about creating a struct, and persisting the struct through
serialization. This struct could be a public property of class A. But if I
do this, there are some downsides because the purpose of the struct
would
be
simply to support serialization, and serialization seems to be supported by
classes and the serialization attributes ([Serialized] and
[NonSerializable]) without the need for structs.

Any ideas on this would be greatly appreciated.
 
S

Scott Simes

I discovered something that's pretty important: One of the fields in my
class was of type System.Data.SqlTypes.SqlInt32. When I looked at the online
docs, this structure is not Serializable. This was the data type that was
"breaking" the "serializability" of my object!



I'm not sure how to handle this, since I don't believe I can change the
serialization attribute of a system structure. The reason I'm using SqlInt32
rather than Int32 (or just int) is that SqlInt32 supports a value of null,
which I need because this value is ultimately provided as an argument to a
stored procedure, and I need to pass nulls in certain circumstances because
it is a requirement of the stored procedure...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top