Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using ISerializable with DataContractSerializer, how do I stop the serializer from outputting type information?

To get more control over serialization, I have converted a class from [DataContract] to [Serializable], implementing both GetObjectData and the special deserializing constructor. When I do this, the XML emitted now has type information applied to all elements. I don't want this superfluous information, and I'm wondering how to inform the serializer to not output it.

Here's the sample code that uses [DataContract]:

[DataContract(Namespace = "")]
class Test 
{
    public Test() { }
    [DataMember]
    public Nullable<int> NullableNumber = 7;
    [DataMember]
    public int Number = 5;

    public static void Go()
    {
        var test = new Test();
        var dcs = new DataContractSerializer(typeof(Test));
        using (var s = new StreamWriter("test.xml"))
        {
            dcs.WriteObject(s.BaseStream, test);
        }
    }        
}

This outputs the following XML (notice no type info on Nullable Number and Number--this is the desired output):

<Test xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <NullableNumber>7</NullableNumber>
  <Number>5</Number>
</Test>

If I modify the above code as follows (adding [Serializable], : ISerializable, and the two serialization methods):

[Serializable]
class Test : ISerializable
{
    public Test() { }
    public Nullable<int> NullableNumber = 7;
    public int Number = 5;

    public static void Go()
    {
        var test = new Test();
        var dcs = new DataContractSerializer(typeof(Test));
        using (var s = new StreamWriter("test.xml"))
        {
            dcs.WriteObject(s.BaseStream, test);
        }
    }        
    public Test(SerializationInfo info, StreamingContext context)
    {
        NullableNumber = info.GetInt32("NullableNumber");
        Number = info.GetInt32("Number");
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("NullableNumber", NullableNumber);
        info.AddValue("Number", Number);
    }
}

It now emits the following XML. Notice the type information (i:type="x:int") added to each element.

<Test xmlns="http://schemas.datacontract.org/2004/07/XMLSerialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema">
  <NullableNumber i:type="x:int" xmlns="">7</NullableNumber>
  <Number i:type="x:int" xmlns="">5</Number>
</Test>

Why is it doing this? How do I stop it from doing it?

Thanks!

like image 216
Eric Avatar asked Jan 19 '26 02:01

Eric


2 Answers

If you want full control over serialization to xml, you can use XmlSerializer

public class Test
{
    [XmlIgnore]
    public Nullable<int> NullableNumber = 7;

    [XmlElement("NullableNumber")]
    public int NullableNumberValue
    {
        get { return NullableNumber.Value; }
        set { NullableNumber = value; }
    }

    public bool ShouldSerializeNullableNumberValue()
    {
        return NullableNumber.HasValue;
    }

    [XmlElement]
    public int Number = 5;
}

sample serialization code:

static void Main(string[] args)
{
    XmlSerializer serializer = new XmlSerializer(typeof(Test));
    serializer.Serialize(Console.Out, new Test());
}

results:

<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Number>5</Number>
  <NullableNumber>7</NullableNumber>
</Test>
like image 126
Dmitry Kolchev Avatar answered Jan 21 '26 14:01

Dmitry Kolchev


Starting in .Net Framework 4.5 (and .Net Core 1.0), this is possible using the DataContractJsonSerializerSettings class:

DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings
{
    EmitTypeInformation = EmitTypeInformation.Never
};
var dcs = new DataContractSerializer(typeof(Test), settings);

The EmitTypeInformation settings tells the serializer not to output the (annoying?) __type parameter during serialization.

There are a range of other useful settings available. Here is the docs page for DataContractJsonSerializerSettings.

like image 42
Martin Avatar answered Jan 21 '26 14:01

Martin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!