4

I'm reading up on serialization, and have so far been messing with BinaryFormatter and SoapFormatter. So far, so good - and everything have both Serialized and Deserialized perfectly.

However, when I try the code below, I would expect my datafile to NOT contains the info for Name - and it does. Why would it contain that, when I specify SoapIgnore on the field?

I also tried with SoapAttribute("SomeAttribute") on the Age-field, and that didn't make any difference either. The framework version is set to 2.0, but the same thing happens in 3.5 and 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;
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433

5 Answers5

10

Use [NonSerialized] instead of [SoapIgnore]

Furthermore, this is an older (and aging) API. Not directly wrong but be sure to read up on XmlSerialization and ProtoBuf as well.

And be careful not to mix the API's up. Serialization is part of SOAP communication but not the same. SoapAttribute is not involved in bare Serialization.

H H
  • 263,252
  • 30
  • 330
  • 514
  • Nope. Not correct. [NonSerialized] is for the BinaryFormatter. [SoapIgnore] is for the SoapFormatter. [XmlIgnore] is for the XmlSerializer. – Peter Olsen Sep 03 '10 at 11:40
  • @Peter: Are you sure? From MSDN: When using the BinaryFormatter or SoapFormatter classes to serialize an object, use the NonSerializedAttribute attribute ...., http://msdn.microsoft.com/en-us/library/system.nonserializedattribute.aspx – H H Sep 03 '10 at 11:42
  • 1
    @Peter: According to the docs http://msdn.microsoft.com/en-us/library/system.xml.serialization.soapattributes.soapignore.aspx [SoapIgnore] is for the XMLSerializer, not the SoapFormatter – Iain Ward Sep 03 '10 at 11:42
  • Actually, I'd stay away from the XML Serializer as well, unless you require control over the exact format of the XML. It's in the process of being dropped, along with ASMX web services. – John Saunders Sep 03 '10 at 11:50
  • So how would I go about serializing an object either through BinaryFormatter, SoapFormatter or XmlSerializer, where I have control over which fields is serialized? The only way seems to be implemented ISerializable - and that might be a TAD overkill. – Peter Olsen Sep 03 '10 at 11:53
  • OK @John, thanks for the tip. Do you have a link for the ASMX state of affairs? – H H Sep 03 '10 at 11:53
  • I found a solution - I answered it below. It seems that the SoapFormatter uses NonSerialized just like the BinaryFormatter does. – Peter Olsen Sep 03 '10 at 12:01
  • And it seems that the MS Press book I'm reading is wrong, in listing SoapIgnore and SoapAttribute alongside SoapFormatters. – Peter Olsen Sep 03 '10 at 12:02
  • @Henk: no single link, unfortunately. The strongest hint is in Ed Pinto's reply to https://connect.microsoft.com/VisualStudio/feedback/details/362727/xsd-exe-incorrect-class-generated-for-abstract-type-with-derived-types. That and the fact that ASMX web services are replaced by WCF, and XML Serialization has only limited applicability to WCF. – John Saunders Sep 03 '10 at 12:06
1

Because serialization and SOAP aren't the same. You have Name marked as public, so the serializer will serialize/deserialize it. If you want it not to appear in a serialization you should change its protection level to protected.

Joel Etherton
  • 37,325
  • 10
  • 89
  • 104
  • This isn't only way to ignore some fields during serialization. – Bart Sep 03 '10 at 11:45
  • There is a SoapFormatter which is designed to serialized data. I'm not talking about a webservice soap envelope. The MSDN it self states the following about SoapFormatters: "Serializes and deserializes an object, or an entire graph of connected objects, in SOAP format." – Peter Olsen Sep 03 '10 at 11:49
  • @Bart, @Peter Olsen - I read a little more into your question and some of the responses, and my "answer" isn't complete or accurate. I was tempted to delete it, but that would deprive potential downvoters of a clear and present opportunity. – Joel Etherton Sep 03 '10 at 12:26
1

From the docs it states that the [SoapIgnore] attribute tells the XMLSerializer not to serialize this property, and it doesn't mention the SoapFormatter so I assume it doesn't apply to it, even though the name suggests it does

Iain Ward
  • 9,850
  • 5
  • 34
  • 41
  • If I use an XmlSerializer, and use the [SoapIgnore] attribute, it serializes the field. If I change the attribute to [XmlIgnore] it correctly ignores the field. It just makes no sense, that there is no way to tell the serializer, that a given public field shouldn't be serialized. Lets say that I have string firstname, lastname, fullname, and fullname is in the ctor set to firstname +" "+ lastname. Why would I then want to serialize fullname? But I need fullname to be public. – Peter Olsen Sep 03 '10 at 11:45
  • [NonSerialized] seems to make the SoapFormatter ignore the field. – Peter Olsen Sep 03 '10 at 12:21
1

The following code works. It seems that the SoapFormatter uses the same attributes as the BinaryFormatter does - the [NonSerialized] attribute. This however goes against what the MS Press book I'm reading states. It lists SoapIgnore, SoapAttribute and others as attributes that works with the SoapFormatter when serializing data.

This code creates two files, none of them having the Name-field.

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

Have a look at this question: Applying SoapIgnore attribute doesn't take any effect to serialization result

Community
  • 1
  • 1
Chris Conway
  • 16,269
  • 23
  • 96
  • 113
  • The answer to that question states, that the SoapIgnore attribute is only for webservices. My question origins from reading the MS Press book for 70-536, where it clearly states that SoapIgnore and SoapAttribute works in union with SoapFormatter for serializing objects. – Peter Olsen Sep 03 '10 at 11:54
  • Right, but those books are notorious for having mistakes in them. Have you checked the book corrections page to see if it's listed? http://www.microsoft.com/learning/en/us/training/format-books-support.aspx#tab2 – Chris Conway Sep 03 '10 at 12:58