Пользовательская сериализация с DataContractSerializer - PullRequest
10 голосов
/ 01 июля 2010

В настоящее время я использую классы-обертки для своих наборов данных, чтобы реализовать пользовательскую сериализацию. Я хотел бы использовать DataContractSerializer (больше похоже на то, чтобы использовать его), но все еще поддерживать настраиваемую сериализацию. Проблема в том, что атрибуты [DataContract] и [Serializable], похоже, не очень хорошо ладят ... как я могу переопределить сериализацию и поддерживать ОБА DataContract & ISerializable сериализацию? Код для класса-обёртки DataSet приведён здесь:

[Serializable()]    
[System.Runtime.InteropServices.ComVisible(false)]
public class TestDatasetWrapper : TestDataSet, ISerializable
{
    public TestDatasetWrapper()
        : base()
    {}

    protected TestDatasetWrapper(SerializationInfo info, StreamingContext context)
    {
        SerializationHelper.DeserializeTypedDataSet(info, this);
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        SerializationHelper.AddTypedDataSetObjectData(info, this);
    }
}

Спасибо!

1 Ответ

13 голосов
/ 01 июля 2010

DataContractAttribute и SerializableAttribute могут использоваться вместе.Бонус здесь заключается в том, что вам также не нужно использовать отдельные сериализаторы.DataContractSerialzer - это XmlObjectSerializer, который сам поддерживает [Serializable].Например:

[Serializable]
public class TestClass
{
    public string Name { get; set; }
}

{
    var formatter = new DataContractSerializer(typeof(TestClass));
    using (var stream = new MemoryStream())
    {
        var instance = new TestClass { Name = "Matt" };
        formatter.WriteObject(stream, instance);

        stream.Seek(0, SeekOrigin.Begin);

        var second = (TestClass) formatter.ReadObject(stream);
        Console.WriteLine(second.Name);
    }
}

OUTPUT : "Matt"

Используя только атрибут SerializableAttribute, мы можем успешно сериализовать и десериализовать объект, используя DataContractSerializer ...

Используя ISerializable, мы можем сделать то же самое:

[Serializable]
public class TestClass2 : ISerializable
{
    public TestClass2() { }
    protected TestClass2(SerializationInfo info, StreamingContext context)
    {
        Name = info.GetString("name").ToUpper();
    }

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

    public string Name { get; set; }
}

{
    var formatter = new DataContractSerializer(typeof(TestClass2));
    using (var stream = new MemoryStream())
    {
        var instance = new TestClass2 { Name = "Matt" };
        formatter.WriteObject(stream, instance);

        stream.Seek(0, SeekOrigin.Begin);

        var second = (TestClass2)formatter.ReadObject(stream);
        Console.WriteLine(second.Name);
    }
}

ВЫВОД : "MATT"

И с атрибутом DataContractAttribute:

[DataContract, Serializable]
public class TestClass3
{
    public int Age { get; set; }

    [DataMember]
    public string Name { get; set; }
}

{
    var formatter = new DataContractSerializer(typeof(TestClass3));
    using (var stream = new MemoryStream())
    {
        var instance = new TestClass3 { Name = "Matt", Age = 26 };
        formatter.WriteObject(stream, instance);

        stream.Seek(0, SeekOrigin.Begin);

        var second = (TestClass3)formatter.ReadObject(stream);
        Console.WriteLine(second.Name);
        Console.WriteLine(second.Age);
    }
}

OUTPUT : "Matt"

OUTPUT : 0

Когда DataContractSerializer встречает тип с DataContractAttribute, он будет использоватьчто вместо передачи сериализации в ее базовый тип, который обрабатывает интерфейсы SerializableAttribute и ISerializable.

Если у вас возникли проблемы, это с сериализацией, с десериализацией или с обоими?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...