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

XmlSerialization base classes

P: n/a
Good afternoon everyone. I'm running into a problem deserializing a stream
using the XmlSerializer. A stored procedure returns the following from SQL
Server:

<Student StudentId="1" Status="1" Gpa="3.50">
<Person Id="1" FirstName="FirstName0" LastName="LastName0"
MiddleInitial="W"/>
</Student>

In my code, person is the base class and student extends it. When I
instantiate the XmlSerializer I use the following overload: XmlSerializer (
Type, Type [ ] ). The first parameter is the derived type, Student. The
second parameter, the Type [ ] contains the base type, Person.

The student information deserializes correctly into a student object.
However, all of the base properties are not populated. I have tried using
the XmlInclude decoration on the base class, directing it to include Student
as a viable type. That also has not worked. All of the properties in both
classes are public, and if I try to deserialize an instance of Person from
Xml it works perfectly.

Has anyone run into this before? Does anyone know how to get around the
problem sort of implementing IXmlSerializable on the derived class?

Thanks everyone.

Jan 19 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
I'm not sure why you're using the particular overload you're using, but that
is not necessarily important.

Also, the fact that the Student class is derived from the Person class is
unimportant. Remember that all classes, except for Object, are derived, at
least from Object.

Properties that are serialized must have a getter and a setter. In addition,
the properties themselves must be serializable. Classes that implement
IEnumerable must implement a public Add method to be serializable. Classes
that implement ICollection must implement a public Item indexer. If any
members of your Student class are of these types, make sure that they can be
serialized.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.

"Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
news:E6**********************************@microsof t.com...
Good afternoon everyone. I'm running into a problem deserializing a
stream
using the XmlSerializer. A stored procedure returns the following from
SQL
Server:

<Student StudentId="1" Status="1" Gpa="3.50">
<Person Id="1" FirstName="FirstName0" LastName="LastName0"
MiddleInitial="W"/>
</Student>

In my code, person is the base class and student extends it. When I
instantiate the XmlSerializer I use the following overload: XmlSerializer
(
Type, Type [ ] ). The first parameter is the derived type, Student. The
second parameter, the Type [ ] contains the base type, Person.

The student information deserializes correctly into a student object.
However, all of the base properties are not populated. I have tried using
the XmlInclude decoration on the base class, directing it to include
Student
as a viable type. That also has not worked. All of the properties in
both
classes are public, and if I try to deserialize an instance of Person from
Xml it works perfectly.

Has anyone run into this before? Does anyone know how to get around the
problem sort of implementing IXmlSerializable on the derived class?

Thanks everyone.

Jan 20 '06 #2

P: n/a
Kevin, thanks for getting back to me. I assumed that the inheritance chain
was important because of who the XmlSerializer works. Let me include some of
the code:

[XmlRoot ( "Person", IsNullable = true, Namespace = "" )]
[XmlInclude ( typeof ( Student ) )]
public class Person
{
/// <summary>
/// Provides protected access to private member _IsDirty to derived objects.
/// </summary>
[ XmlIgnore ( )]
public bool IsDirty
{
get { return _IsDirty; }
}

/// <summary>
/// Provides public access to the private
/// member _Id.
/// </summary>
[XmlAttribute ( )]
public int Id
{
get { return _Id; }
set
{
_Id = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _FirstName.
/// </summary>
[XmlAttribute ( )]
public string FirstName
{
get { return _FirstName; }
set
{
_FirstName = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _LastName.
/// </summary>
[XmlAttribute ( )]
public string LastName
{
get { return _LastName; }
set
{
_LastName = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _MiddleInitial.
/// </summary>
[XmlAttribute ( )]
public string MiddleInitial
{
get { return _MiddleInitial; }
set
{
_MiddleInitial = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _AddressInfo.
/// </summary>
public Address [ ] AddressInfo
{
get { return _AddressInfo; }
set
{
_AddressInfo = value;
_IsDirty = true;
}
}

#endregion

#region Constructors

/// <summary>
/// Default constructor. Creates a new instance with no parameters.
/// </summary>
public Person ( ) { }

#endregion

}

[ XmlRoot ( "Student", IsNullable = true, Namespace = "" ) ]
public class Student : Person
{
#region Properties

/// <summary>
/// Provides protected access to private member _IsDirty to derived objects.
/// </summary>
[XmlIgnore]
protected new bool IsDirty
{
get { return _IsDirty; }
}

/// <summary>
/// Provides public access to the private memeber _StudentId.
/// </summary>
[ XmlAttribute ( ) ]
public int StudentId
{
get { return _StudentId; }
set
{
_StudentId = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to private member _Courses.
/// </summary>
public AssignedCourse [ ] CourseCollection
{
get { return _CourseCollection; }
set
{
_CourseCollection = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to private member _Status.
/// </summary>
[XmlIgnore]
public Prototype.Enumeration.StudentStatus CurrentStatus
{
get { return _Status; }
set
{
_Status = value;
_IsDirty = true;
}
}

[XmlAttribute ( )]
public int Status
{
get { return ( int ) _Status; }
set
{
_Status = ( Prototype.Enumeration.StudentStatus ) value;
_IsDirty = true;
}

}

/// <summary>
/// Provides public access to private member _Gpa.
/// </summary>
[XmlAttribute ( )]
public float Gpa
{
get { return _Gpa; }
set
{
_Gpa = value;
_IsDirty = true;
}
}

#endregion

/// <summary>
/// Default constructor. Creates a new instance with no parameters.
/// </summary>
public Student ( ) : base ( ) { }

}

Each property references a private field (not included in post). The reason
I used the particular overload is because Student is derived from Person...
according to the documentation:

"You can also use the extraTypes parameter to specify types derived from a
base class. For example, suppose a base class named Phone exists, and a class
named InternationalPhone derives from it. Use the extraTypes parameter to
specify the derived type as well."

Any ideas on what might be wrong?

"Kevin Spencer" wrote:
I'm not sure why you're using the particular overload you're using, but that
is not necessarily important.

Also, the fact that the Student class is derived from the Person class is
unimportant. Remember that all classes, except for Object, are derived, at
least from Object.

Properties that are serialized must have a getter and a setter. In addition,
the properties themselves must be serializable. Classes that implement
IEnumerable must implement a public Add method to be serializable. Classes
that implement ICollection must implement a public Item indexer. If any
members of your Student class are of these types, make sure that they can be
serialized.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.

"Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
news:E6**********************************@microsof t.com...
Good afternoon everyone. I'm running into a problem deserializing a
stream
using the XmlSerializer. A stored procedure returns the following from
SQL
Server:

<Student StudentId="1" Status="1" Gpa="3.50">
<Person Id="1" FirstName="FirstName0" LastName="LastName0"
MiddleInitial="W"/>
</Student>

In my code, person is the base class and student extends it. When I
instantiate the XmlSerializer I use the following overload: XmlSerializer
(
Type, Type [ ] ). The first parameter is the derived type, Student. The
second parameter, the Type [ ] contains the base type, Person.

The student information deserializes correctly into a student object.
However, all of the base properties are not populated. I have tried using
the XmlInclude decoration on the base class, directing it to include
Student
as a viable type. That also has not worked. All of the properties in
both
classes are public, and if I try to deserialize an instance of Person from
Xml it works perfectly.

Has anyone run into this before? Does anyone know how to get around the
problem sort of implementing IXmlSerializable on the derived class?

Thanks everyone.


Jan 20 '06 #3

P: n/a
Hi Chris,
I assumed that the inheritance chain
was important because of who the XmlSerializer works.
You may be right. Turns out I've serialized inherited classes, but I wrote
custom serializers. I've also used XmlSerializer, but not on inherited
classes! So I can't be sure, now that I've looked back at my previous
experiences.

So, at this point I can tell you this much from my personal experience, and
from the example in the SDK. I know that I have had problems in the past
with over-using and mis-using XML attributes. I noticed that the only XML
attribute in the example was for the object array in the Teacher class. For
the most part, the XmlSerializer doesn't need attributes to do
serialization. They are available for customized serialization, but the
XmlSerializer uses Reflection for almost everything it does. You might try
removing most of the attributes you've added, and see how that works out.
Take another look at the example.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.
"Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
news:BF**********************************@microsof t.com... Kevin, thanks for getting back to me. I assumed that the inheritance
chain
was important because of who the XmlSerializer works. Let me include some
of
the code:

[XmlRoot ( "Person", IsNullable = true, Namespace = "" )]
[XmlInclude ( typeof ( Student ) )]
public class Person
{
/// <summary>
/// Provides protected access to private member _IsDirty to derived
objects.
/// </summary>
[ XmlIgnore ( )]
public bool IsDirty
{
get { return _IsDirty; }
}

/// <summary>
/// Provides public access to the private
/// member _Id.
/// </summary>
[XmlAttribute ( )]
public int Id
{
get { return _Id; }
set
{
_Id = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _FirstName.
/// </summary>
[XmlAttribute ( )]
public string FirstName
{
get { return _FirstName; }
set
{
_FirstName = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _LastName.
/// </summary>
[XmlAttribute ( )]
public string LastName
{
get { return _LastName; }
set
{
_LastName = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _MiddleInitial.
/// </summary>
[XmlAttribute ( )]
public string MiddleInitial
{
get { return _MiddleInitial; }
set
{
_MiddleInitial = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _AddressInfo.
/// </summary>
public Address [ ] AddressInfo
{
get { return _AddressInfo; }
set
{
_AddressInfo = value;
_IsDirty = true;
}
}

#endregion

#region Constructors

/// <summary>
/// Default constructor. Creates a new instance with no parameters.
/// </summary>
public Person ( ) { }

#endregion

}

[ XmlRoot ( "Student", IsNullable = true, Namespace = "" ) ]
public class Student : Person
{
#region Properties

/// <summary>
/// Provides protected access to private member _IsDirty to derived
objects.
/// </summary>
[XmlIgnore]
protected new bool IsDirty
{
get { return _IsDirty; }
}

/// <summary>
/// Provides public access to the private memeber _StudentId.
/// </summary>
[ XmlAttribute ( ) ]
public int StudentId
{
get { return _StudentId; }
set
{
_StudentId = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to private member _Courses.
/// </summary>
public AssignedCourse [ ] CourseCollection
{
get { return _CourseCollection; }
set
{
_CourseCollection = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to private member _Status.
/// </summary>
[XmlIgnore]
public Prototype.Enumeration.StudentStatus CurrentStatus
{
get { return _Status; }
set
{
_Status = value;
_IsDirty = true;
}
}

[XmlAttribute ( )]
public int Status
{
get { return ( int ) _Status; }
set
{
_Status = ( Prototype.Enumeration.StudentStatus ) value;
_IsDirty = true;
}

}

/// <summary>
/// Provides public access to private member _Gpa.
/// </summary>
[XmlAttribute ( )]
public float Gpa
{
get { return _Gpa; }
set
{
_Gpa = value;
_IsDirty = true;
}
}

#endregion

/// <summary>
/// Default constructor. Creates a new instance with no parameters.
/// </summary>
public Student ( ) : base ( ) { }

}

Each property references a private field (not included in post). The
reason
I used the particular overload is because Student is derived from
Person...
according to the documentation:

"You can also use the extraTypes parameter to specify types derived from a
base class. For example, suppose a base class named Phone exists, and a
class
named InternationalPhone derives from it. Use the extraTypes parameter to
specify the derived type as well."

Any ideas on what might be wrong?

"Kevin Spencer" wrote:
I'm not sure why you're using the particular overload you're using, but
that
is not necessarily important.

Also, the fact that the Student class is derived from the Person class is
unimportant. Remember that all classes, except for Object, are derived,
at
least from Object.

Properties that are serialized must have a getter and a setter. In
addition,
the properties themselves must be serializable. Classes that implement
IEnumerable must implement a public Add method to be serializable.
Classes
that implement ICollection must implement a public Item indexer. If any
members of your Student class are of these types, make sure that they can
be
serialized.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.

"Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
news:E6**********************************@microsof t.com...
> Good afternoon everyone. I'm running into a problem deserializing a
> stream
> using the XmlSerializer. A stored procedure returns the following from
> SQL
> Server:
>
> <Student StudentId="1" Status="1" Gpa="3.50">
> <Person Id="1" FirstName="FirstName0" LastName="LastName0"
> MiddleInitial="W"/>
> </Student>
>
> In my code, person is the base class and student extends it. When I
> instantiate the XmlSerializer I use the following overload:
> XmlSerializer
> (
> Type, Type [ ] ). The first parameter is the derived type, Student.
> The
> second parameter, the Type [ ] contains the base type, Person.
>
> The student information deserializes correctly into a student object.
> However, all of the base properties are not populated. I have tried
> using
> the XmlInclude decoration on the base class, directing it to include
> Student
> as a viable type. That also has not worked. All of the properties in
> both
> classes are public, and if I try to deserialize an instance of Person
> from
> Xml it works perfectly.
>
> Has anyone run into this before? Does anyone know how to get around
> the
> problem sort of implementing IXmlSerializable on the derived class?
>
> Thanks everyone.
>


Jan 20 '06 #4

P: n/a
Hey Kevin,

I need those attribute decorations because the stored procedures I'm using
are returning data using "FOR XML AUTO". This generates the XML using
attributes instead of elements. The default deserialization method will look
for XmlElements to populate properties with. By adding the XmlAttribute
decoration to my properties it will direct the serialization processes to
look for the attributes that stored procedures return.

I created some simple class... Junk and DerivedJunk to test this further. I
think the problem is in the format that the XML comes back with. The base
class is contained in a nested element of the derived class:

<DerivedJunk JunkId="1" SpecialJunk="Speical Junk 1">
<Junk Id="1" SomeJunk="Test 1" />
</DerivedJunk>

Normally this format would indicate that the Junk element is a collection
that belongs to DerivedJunk. I'm assuming that this would direct the
XmlSerializer to look for a Junk object that has a public read/write property
associated with it. That is significantly different that looking for
additional public properties in the DerivedJunk instance which is what I want
to happen.

Perhaps this is a limitation of the XmlSerializer...? In which case I need
to use custom serialization and implement IXmlSerializable. This is
unfortunate because now using the XmlSerializer as a middle tier for data
access becomes much more complicated. Any derived class will have to
describe the manner in which its base class is populate. How can this be
right?

The other option is to try and use FOR XML EXPLICIT. That is a daunting
task however. The syntax is difficult to use in my opinion, and the SQL is
much harder to interpret by other developers.

If anyone has any other input or suggestions I would be very interested in
hearing about them. Thanks again.
"Kevin Spencer" wrote:
Hi Chris,
I assumed that the inheritance chain
was important because of who the XmlSerializer works.


You may be right. Turns out I've serialized inherited classes, but I wrote
custom serializers. I've also used XmlSerializer, but not on inherited
classes! So I can't be sure, now that I've looked back at my previous
experiences.

So, at this point I can tell you this much from my personal experience, and
from the example in the SDK. I know that I have had problems in the past
with over-using and mis-using XML attributes. I noticed that the only XML
attribute in the example was for the object array in the Teacher class. For
the most part, the XmlSerializer doesn't need attributes to do
serialization. They are available for customized serialization, but the
XmlSerializer uses Reflection for almost everything it does. You might try
removing most of the attributes you've added, and see how that works out.
Take another look at the example.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.
"Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
news:BF**********************************@microsof t.com...
Kevin, thanks for getting back to me. I assumed that the inheritance
chain
was important because of who the XmlSerializer works. Let me include some
of
the code:

[XmlRoot ( "Person", IsNullable = true, Namespace = "" )]
[XmlInclude ( typeof ( Student ) )]
public class Person
{
/// <summary>
/// Provides protected access to private member _IsDirty to derived
objects.
/// </summary>
[ XmlIgnore ( )]
public bool IsDirty
{
get { return _IsDirty; }
}

/// <summary>
/// Provides public access to the private
/// member _Id.
/// </summary>
[XmlAttribute ( )]
public int Id
{
get { return _Id; }
set
{
_Id = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _FirstName.
/// </summary>
[XmlAttribute ( )]
public string FirstName
{
get { return _FirstName; }
set
{
_FirstName = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _LastName.
/// </summary>
[XmlAttribute ( )]
public string LastName
{
get { return _LastName; }
set
{
_LastName = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _MiddleInitial.
/// </summary>
[XmlAttribute ( )]
public string MiddleInitial
{
get { return _MiddleInitial; }
set
{
_MiddleInitial = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to the private
/// member _AddressInfo.
/// </summary>
public Address [ ] AddressInfo
{
get { return _AddressInfo; }
set
{
_AddressInfo = value;
_IsDirty = true;
}
}

#endregion

#region Constructors

/// <summary>
/// Default constructor. Creates a new instance with no parameters.
/// </summary>
public Person ( ) { }

#endregion

}

[ XmlRoot ( "Student", IsNullable = true, Namespace = "" ) ]
public class Student : Person
{
#region Properties

/// <summary>
/// Provides protected access to private member _IsDirty to derived
objects.
/// </summary>
[XmlIgnore]
protected new bool IsDirty
{
get { return _IsDirty; }
}

/// <summary>
/// Provides public access to the private memeber _StudentId.
/// </summary>
[ XmlAttribute ( ) ]
public int StudentId
{
get { return _StudentId; }
set
{
_StudentId = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to private member _Courses.
/// </summary>
public AssignedCourse [ ] CourseCollection
{
get { return _CourseCollection; }
set
{
_CourseCollection = value;
_IsDirty = true;
}
}

/// <summary>
/// Provides public access to private member _Status.
/// </summary>
[XmlIgnore]
public Prototype.Enumeration.StudentStatus CurrentStatus
{
get { return _Status; }
set
{
_Status = value;
_IsDirty = true;
}
}

[XmlAttribute ( )]
public int Status
{
get { return ( int ) _Status; }
set
{
_Status = ( Prototype.Enumeration.StudentStatus ) value;
_IsDirty = true;
}

}

/// <summary>
/// Provides public access to private member _Gpa.
/// </summary>
[XmlAttribute ( )]
public float Gpa
{
get { return _Gpa; }
set
{
_Gpa = value;
_IsDirty = true;
}
}

#endregion

/// <summary>
/// Default constructor. Creates a new instance with no parameters.
/// </summary>
public Student ( ) : base ( ) { }

}

Each property references a private field (not included in post). The
reason
I used the particular overload is because Student is derived from
Person...
according to the documentation:

"You can also use the extraTypes parameter to specify types derived from a
base class. For example, suppose a base class named Phone exists, and a
class
named InternationalPhone derives from it. Use the extraTypes parameter to
specify the derived type as well."

Any ideas on what might be wrong?

"Kevin Spencer" wrote:
I'm not sure why you're using the particular overload you're using, but
that
is not necessarily important.

Also, the fact that the Student class is derived from the Person class is
unimportant. Remember that all classes, except for Object, are derived,
at
least from Object.

Properties that are serialized must have a getter and a setter. In
addition,
the properties themselves must be serializable. Classes that implement
IEnumerable must implement a public Add method to be serializable.
Classes
that implement ICollection must implement a public Item indexer. If any
members of your Student class are of these types, make sure that they can
be
serialized.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.

"Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
news:E6**********************************@microsof t.com...
> Good afternoon everyone. I'm running into a problem deserializing a
> stream
> using the XmlSerializer. A stored procedure returns the following from
> SQL
> Server:
>
> <Student StudentId="1" Status="1" Gpa="3.50">
> <Person Id="1" FirstName="FirstName0" LastName="LastName0"
> MiddleInitial="W"/>
> </Student>
>
> In my code, person is the base class and student extends it. When I
> instantiate the XmlSerializer I use the following overload:
> XmlSerializer
> (
> Type, Type [ ] ). The first parameter is the derived type, Student.
> The
> second parameter, the Type [ ] contains the base type, Person.
>
> The student information deserializes correctly into a student object.
> However, all of the base properties are not populated. I have tried
> using
> the XmlInclude decoration on the base class, directing it to include
> Student

Jan 20 '06 #5

P: n/a
Hi Chris,

I can understand that about the XmlAttribute attributes. But you might want
to strip out the other XML attributes from your class definitions.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.

"Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
news:32**********************************@microsof t.com...
Hey Kevin,

I need those attribute decorations because the stored procedures I'm using
are returning data using "FOR XML AUTO". This generates the XML using
attributes instead of elements. The default deserialization method will
look
for XmlElements to populate properties with. By adding the XmlAttribute
decoration to my properties it will direct the serialization processes to
look for the attributes that stored procedures return.

I created some simple class... Junk and DerivedJunk to test this further.
I
think the problem is in the format that the XML comes back with. The base
class is contained in a nested element of the derived class:

<DerivedJunk JunkId="1" SpecialJunk="Speical Junk 1">
<Junk Id="1" SomeJunk="Test 1" />
</DerivedJunk>

Normally this format would indicate that the Junk element is a collection
that belongs to DerivedJunk. I'm assuming that this would direct the
XmlSerializer to look for a Junk object that has a public read/write
property
associated with it. That is significantly different that looking for
additional public properties in the DerivedJunk instance which is what I
want
to happen.

Perhaps this is a limitation of the XmlSerializer...? In which case I
need
to use custom serialization and implement IXmlSerializable. This is
unfortunate because now using the XmlSerializer as a middle tier for data
access becomes much more complicated. Any derived class will have to
describe the manner in which its base class is populate. How can this be
right?

The other option is to try and use FOR XML EXPLICIT. That is a daunting
task however. The syntax is difficult to use in my opinion, and the SQL
is
much harder to interpret by other developers.

If anyone has any other input or suggestions I would be very interested in
hearing about them. Thanks again.
"Kevin Spencer" wrote:
Hi Chris,
> I assumed that the inheritance chain
> was important because of who the XmlSerializer works.


You may be right. Turns out I've serialized inherited classes, but I
wrote
custom serializers. I've also used XmlSerializer, but not on inherited
classes! So I can't be sure, now that I've looked back at my previous
experiences.

So, at this point I can tell you this much from my personal experience,
and
from the example in the SDK. I know that I have had problems in the past
with over-using and mis-using XML attributes. I noticed that the only XML
attribute in the example was for the object array in the Teacher class.
For
the most part, the XmlSerializer doesn't need attributes to do
serialization. They are available for customized serialization, but the
XmlSerializer uses Reflection for almost everything it does. You might
try
removing most of the attributes you've added, and see how that works out.
Take another look at the example.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Who is Mighty Abbott?
A twin turret scalawag.
"Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
news:BF**********************************@microsof t.com...
> Kevin, thanks for getting back to me. I assumed that the inheritance
> chain
> was important because of who the XmlSerializer works. Let me include
> some
> of
> the code:
>
> [XmlRoot ( "Person", IsNullable = true, Namespace = "" )]
> [XmlInclude ( typeof ( Student ) )]
> public class Person
> {
> /// <summary>
> /// Provides protected access to private member _IsDirty to derived
> objects.
> /// </summary>
> [ XmlIgnore ( )]
> public bool IsDirty
> {
> get { return _IsDirty; }
> }
>
> /// <summary>
> /// Provides public access to the private
> /// member _Id.
> /// </summary>
> [XmlAttribute ( )]
> public int Id
> {
> get { return _Id; }
> set
> {
> _Id = value;
> _IsDirty = true;
> }
> }
>
> /// <summary>
> /// Provides public access to the private
> /// member _FirstName.
> /// </summary>
> [XmlAttribute ( )]
> public string FirstName
> {
> get { return _FirstName; }
> set
> {
> _FirstName = value;
> _IsDirty = true;
> }
> }
>
> /// <summary>
> /// Provides public access to the private
> /// member _LastName.
> /// </summary>
> [XmlAttribute ( )]
> public string LastName
> {
> get { return _LastName; }
> set
> {
> _LastName = value;
> _IsDirty = true;
> }
> }
>
> /// <summary>
> /// Provides public access to the private
> /// member _MiddleInitial.
> /// </summary>
> [XmlAttribute ( )]
> public string MiddleInitial
> {
> get { return _MiddleInitial; }
> set
> {
> _MiddleInitial = value;
> _IsDirty = true;
> }
> }
>
> /// <summary>
> /// Provides public access to the private
> /// member _AddressInfo.
> /// </summary>
> public Address [ ] AddressInfo
> {
> get { return _AddressInfo; }
> set
> {
> _AddressInfo = value;
> _IsDirty = true;
> }
> }
>
> #endregion
>
> #region Constructors
>
> /// <summary>
> /// Default constructor. Creates a new instance with no parameters.
> /// </summary>
> public Person ( ) { }
>
> #endregion
>
> }
>
> [ XmlRoot ( "Student", IsNullable = true, Namespace = "" ) ]
> public class Student : Person
> {
> #region Properties
>
> /// <summary>
> /// Provides protected access to private member _IsDirty to derived
> objects.
> /// </summary>
> [XmlIgnore]
> protected new bool IsDirty
> {
> get { return _IsDirty; }
> }
>
> /// <summary>
> /// Provides public access to the private memeber _StudentId.
> /// </summary>
> [ XmlAttribute ( ) ]
> public int StudentId
> {
> get { return _StudentId; }
> set
> {
> _StudentId = value;
> _IsDirty = true;
> }
> }
>
> /// <summary>
> /// Provides public access to private member _Courses.
> /// </summary>
> public AssignedCourse [ ] CourseCollection
> {
> get { return _CourseCollection; }
> set
> {
> _CourseCollection = value;
> _IsDirty = true;
> }
> }
>
> /// <summary>
> /// Provides public access to private member _Status.
> /// </summary>
> [XmlIgnore]
> public Prototype.Enumeration.StudentStatus CurrentStatus
> {
> get { return _Status; }
> set
> {
> _Status = value;
> _IsDirty = true;
> }
> }
>
> [XmlAttribute ( )]
> public int Status
> {
> get { return ( int ) _Status; }
> set
> {
> _Status = ( Prototype.Enumeration.StudentStatus ) value;
> _IsDirty = true;
> }
>
> }
>
> /// <summary>
> /// Provides public access to private member _Gpa.
> /// </summary>
> [XmlAttribute ( )]
> public float Gpa
> {
> get { return _Gpa; }
> set
> {
> _Gpa = value;
> _IsDirty = true;
> }
> }
>
> #endregion
>
> /// <summary>
> /// Default constructor. Creates a new instance with no parameters.
> /// </summary>
> public Student ( ) : base ( ) { }
>
> }
>
> Each property references a private field (not included in post). The
> reason
> I used the particular overload is because Student is derived from
> Person...
> according to the documentation:
>
> "You can also use the extraTypes parameter to specify types derived
> from a
> base class. For example, suppose a base class named Phone exists, and a
> class
> named InternationalPhone derives from it. Use the extraTypes parameter
> to
> specify the derived type as well."
>
> Any ideas on what might be wrong?
>
> "Kevin Spencer" wrote:
>
>> I'm not sure why you're using the particular overload you're using,
>> but
>> that
>> is not necessarily important.
>>
>> Also, the fact that the Student class is derived from the Person class
>> is
>> unimportant. Remember that all classes, except for Object, are
>> derived,
>> at
>> least from Object.
>>
>> Properties that are serialized must have a getter and a setter. In
>> addition,
>> the properties themselves must be serializable. Classes that implement
>> IEnumerable must implement a public Add method to be serializable.
>> Classes
>> that implement ICollection must implement a public Item indexer. If
>> any
>> members of your Student class are of these types, make sure that they
>> can
>> be
>> serialized.
>>
>> --
>> HTH,
>>
>> Kevin Spencer
>> Microsoft MVP
>> ..Net Developer
>> Who is Mighty Abbott?
>> A twin turret scalawag.
>>
>> "Chris Szabo" <Ch********@discussions.microsoft.com> wrote in message
>> news:E6**********************************@microsof t.com...
>> > Good afternoon everyone. I'm running into a problem deserializing a
>> > stream
>> > using the XmlSerializer. A stored procedure returns the following
>> > from
>> > SQL
>> > Server:
>> >
>> > <Student StudentId="1" Status="1" Gpa="3.50">
>> > <Person Id="1" FirstName="FirstName0" LastName="LastName0"
>> > MiddleInitial="W"/>
>> > </Student>
>> >
>> > In my code, person is the base class and student extends it. When I
>> > instantiate the XmlSerializer I use the following overload:
>> > XmlSerializer
>> > (
>> > Type, Type [ ] ). The first parameter is the derived type, Student.
>> > The
>> > second parameter, the Type [ ] contains the base type, Person.
>> >
>> > The student information deserializes correctly into a student
>> > object.
>> > However, all of the base properties are not populated. I have tried
>> > using
>> > the XmlInclude decoration on the base class, directing it to include
>> > Student

Jan 20 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.