Как использовать ISerializable с DataContractSerializer, как остановить сериализатор от вывода информации о типе? - PullRequest
10 голосов
/ 02 апреля 2009

Чтобы получить больше контроля над сериализацией, я преобразовал класс из [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>

Почему он это делает? Как я могу остановить это от этого?

Спасибо!

1 Ответ

0 голосов
/ 03 апреля 2009

Вам нужен ISerializable здесь? Что обычный DataContractSerializer не давал тебе? Если вы вернетесь к этому, он должен работать нормально.

По сути, благодаря реализации настраиваемой сериализации данные больше не основаны на контракте, поэтому имеет для включения этой дополнительной информации, чтобы гарантировать, что она сможет понять ее позже.

Итак: есть ли причина для реализации ISerializable в этом случае?

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