Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
371 views
in Technique[技术] by (71.8m points)

c# - .NET Serialization Ordering

I am trying to serialize some objects using XmlSerializer and inheritance but I am having some problems with ordering the outcome.

Below is an example similar to what I have setup: ~

public class SerializableBase
{
    [XmlElement(Order = 1)]
    public bool Property1 { get; set;}

    [XmlElement(Order = 3)]
    public bool Property3 { get; set;}
}

[XmlRoot("Object")]
public class SerializableObject1 : SerializableBase
{
}

[XmlRoot("Object")]
public class SerializableObject2 : SerializableBase
{
    [XmlElement(Order = 2)]
    public bool Property2 { get; set;}
}

The outcome I want is as follows: ~

<Object>
    <Property1></Property1>
    <Property2></Property2>
    <Property3></Property3>
</Object>

However I am getting an outcome of: ~

<Object>
    <Property1></Property1>
    <Property3></Property3>
    <Property2></Property2>
</Object>

Does anyone know if it is possible or of any alternative?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Technically, from a pure xml perspective, I would say that this is probably a bad thing to want to do.

.NET hides much of the complexity of things like XmlSerialization - in this case, it hides the schema to which your serialized xml should conform.

The inferred schema will use sequence elements to describe the base type, and the extension types. This requires strict ordering -- even if the Deserializer is less strict and accepts out of order elements.

In xml schemas, when defining extension types, the additional elements from the child class must come after the elements from the base class.

you would essentially have a schema that looks something like (xml-y tags removed for clarity)

base
  sequence
    prop1
    prop3

derived1 extends base
  sequence
    <empty>

derived2 extends base
  sequence
    prop2

There's no way to stick a placeholder in between prop1 and prop3 to indicate where the properties from the derived xml can go.

In the end, you have a mismatch between your data format and your business object. Probably your best alternative is to define an object to deal with your xml serialization.

For example

[XmlRoot("Object")
public class SerializableObjectForPersistance
{
    [XmlElement(Order = 1)]
    public bool Property1 { get; set; }

    [XmlElement(Order = 2, IsNullable=true)]
    public bool Property2 { get; set; }

    [XmlElement(Order = 3)]
    public bool Property3 { get; set; }
}

This separates your xml serialization code from your object model. Copy all the values from SerializableObject1 or SerializableObject2 to SerializableObjectForPersistance, and then serialize it.

Essentially, if you want such specific control over the format of your serialized xml that doesn't quite jive with the expectations xml serialization framework, you need to decouple your business object design (inheritance structure in this case) and the responsibility for serialization of that business object.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...