2010-09-03 2 views
4

Я читаю о сериализации и до сих пор путаюсь с BinaryFormatter и SoapFormatter. Пока что так хорошо - и все отлично и сериализовано, и десериализовано.Ошибки сериализации в .NET?

Однако, когда я пробую код ниже, я бы ожидал, что мой файл данных НЕ содержит информацию для Name - и это так. Почему он должен содержать это, когда я укажу SoapIgnore на поле?

Я также пробовал с SoapAttribute("SomeAttribute") по возрасту, и это тоже не имело никакого значения. Версия фрейма установлена ​​в 2.0, но то же самое происходит в 3.5 и 4.0.

using System; 
using System.Runtime.Serialization.Formatters.Soap; 
using System.IO; 
using System.Xml.Serialization; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p = new Person(); 
     p.Age = 42; 
     p.Name = "Mr Smith"; 

     SoapFormatter formatter = new SoapFormatter(); 
     FileStream fs = new FileStream(@"c:\test\data.txt", FileMode.Create); 

     formatter.Serialize(fs, p); 
    } 
} 

[Serializable] 
class Person 
{ 
    public int Age; 
    [SoapIgnore] 
    public string Name; 
} 

ответ

1

Поскольку сериализация и SOAP не совпадают. У вас есть Name, помеченные как общедоступные, поэтому сериализатор сериализует/десериализует его. Если вы хотите, чтобы он не появлялся в сериализации, вы должны изменить его уровень защиты на защищенный.

+0

Это не только способ игнорировать некоторые поля во время сериализации. – Bart

+0

Существует SoapFormatter, который предназначен для сериализации данных. Я не говорю о конверте мыла с веб-сервисом. В MSDN он сам заявляет следующее о SoapFormatters: «Сериализует и десериализует объект или весь график подключенных объектов в формате SOAP». –

+0

@Bart, @Peter Olsen - я прочитал немного больше о вашем вопросе и некоторых ответах, и мой «ответ» не является полным или точным. У меня возникло соблазн удалить его, но это лишило бы потенциальных сторонников ясной и настоящей возможности. –

9

Использование [NonSerialized] вместо [SoapIgnore]

Кроме того, это старая (и старение) API. Не прямо неправильно, но обязательно прочитайте XmlSerialization и ProtoBuf.

И будьте осторожны, чтобы не смешивать API. Сериализация является частью SOAP-связи, но не то же самое. SoapAttribute не участвует в простой сериализации.

+0

Нет. Не верно. [NonSerialized] предназначен для двоичного файла. [SoapIgnore] для SoapFormatter. [XmlIgnore] для XmlSerializer. –

+0

@ Питер: Вы уверены? Из MSDN: при использовании классов BinaryFormatter или SoapFormatter для сериализации объекта используйте атрибут NonSerializedAttribute ...., http://msdn.microsoft.com/en-us/library/system.nonserializedattribute.aspx –

+1

@Peter: Согласно к документам http://msdn.microsoft.com/en-us/library/system.xml.serialization.soapattributes.soapignore.aspx [SoapIgnore] для XMLSerializer, а не SoapFormatter – w69rdy

0
+0

Ответ на этот вопрос гласит, что атрибут SoapIgnore предназначен только для веб-сервисов. Мой вопрос исходит из чтения книги MS Press для 70-536, где четко сказано, что SoapIgnore и SoapAttribute работают в объединении с SoapFormatter для сериализации объектов. –

+0

Правильно, но эти книги печально известны за ошибки в них. Вы проверили страницу коррекции книги, чтобы узнать, указана ли она? http://www.microsoft.com/learning/en/us/training/format-books-support.aspx#tab2 –

1

Из docs он утверждает, что атрибут [SoapIgnore] рассказывает XMLSerializer не сериализовать это свойство, и не говоря уже о SoapFormatter, так что я предполагаю, что это не относится к нему, хотя название предполагает, что это делает

+0

Если я использую XmlSerializer и использую атрибут [SoapIgnore], он сериализует это поле. Если я изменю атрибут на [XmlIgnore], он правильно игнорирует это поле. Просто не имеет смысла указывать сериализатору, что данное публичное поле не должно быть сериализовано. Допустим, что у меня есть строка firstname, lastname, fullname и fullname в каталоге ctor, присваиваемом firstname + "" + lastname. Почему бы мне тогда сериализовать полное имя? Но мне нужно, чтобы имя было общедоступным. –

+0

Хорошо работает [NonSerialized] как @Henk? – w69rdy

+0

[NonSerialized] кажется, что SoapFormatter игнорирует поле. –

1

Следующий код работает. Кажется, что SoapFormatter использует те же атрибуты, что и BinaryFormatter, - атрибут [NonSerialized]. Это, однако, противоречит тому, что говорится в книге MS Press, которую я читаю. Он отображает SoapIgnore, SoapAttribute и другие как атрибуты, которые работают с SoapFormatter при сериализации данных.

Этот код создает два файла, ни одно из которых не имеет поля Имя.

using System; 
using System.Runtime.Serialization.Formatters.Soap; 
using System.IO; 
using System.Xml.Serialization; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p = new Person(); 
     p.Age = 42; 
     p.Name = "Mr Smith"; 

     FormatSoap(p); 
     FormatXml(p); 
    } 

    private static void FormatXml(Person p) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(Person)); 
     FileStream fs = new FileStream(@"c:\test\xmldata.txt", FileMode.Create); 

     serializer.Serialize(fs, p); 
    } 

    private static void FormatSoap(Person p) 
    { 
     SoapFormatter formatter = new SoapFormatter(); 
     FileStream fs = new FileStream(@"c:\test\soapdata.txt", FileMode.Create); 

     formatter.Serialize(fs, p); 
    } 
} 

[Serializable] 
public class Person 
{ 
    public int Age; 
    [XmlIgnore] 
    [NonSerialized] 
    public string Name; 
} 
+0

Конечно, это не значит, что я могу изменить, как я хочу создать созданный soapenvelope - установить некоторые значения для мыльных атрибутов и переименовать другие поля. –

+0

@Peter: какая книга, и когда она была опубликована? –

+1

@John: Это учебный комплект для самостоятельного обучения для экзамена 70-536 (Фонд разработки приложений .Net). Это даже второе издание с 2009 года. –