13

为了更好地控制序列化,我将一个类从 转换[DataContract][Serializable],同时实现GetObjectData了特殊的反序列化构造函数。当我这样做时,发出的 XML 现在具有应用于所有元素的类型信息。我不想要这些多余的信息,我想知道如何通知序列化程序不要输出它。

这是使用的示例代码[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);
        }
    }        
}

这将输出以下 XML(注意 Nullable Number 和 Number 上没有类型信息——这是所需的输出):

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

如果我将上面的代码修改如下(添加[Serializable],:ISerializable,以及两个序列化方法):

[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);
    }
}

它现在发出以下 XML。注意添加到每个元素的类型信息 (i:type="x:int")。

<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>

为什么要这样做?我该如何阻止它这样做?

谢谢!

4

3 回答 3

0

你需要ISerializable这里吗?常客DataContractSerializer没有给你什么?如果你切换回这个,它应该可以正常工作。

基本上,通过实现自定义序列化,数据不再是基于契约的——所以它必须包含这些额外的信息以保证它以后能够理解它。

那么:在这种情况下是否有理由实施ISerializable

于 2009-04-02T23:00:19.813 回答
0

如果要完全控制对 xml 的序列化,可以使用 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;
}

示例序列化代码:

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

结果:

<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>
于 2019-08-29T22:18:39.700 回答
0

从 .Net Framework 4.5(和 .Net Core 1.0)开始,可以使用以下DataContractJsonSerializerSettings类:

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

设置告诉序列化器在序列化过程中EmitTypeInformation不要输出(烦人的?)__type参数。

还有一系列其他有用的设置可用。 DataContractJsonSerializerSettings.

于 2020-01-06T20:32:31.373 回答