views:

222

answers:

2

Hello, I had an odd problem today when I was trying to serialize an object. The object was generated via "Add service reference" from a web service (svcutil.exe).

The problem was that the below property (agencyId) was not being serialized with the rest of the object. Out of desperation I commented the property below it because it had the "XMLIgnoreAttribute" assigned... after I commented the ignored property, the agencyId field serialized as expected.

Can someone please explain to me why this behavior occurred? Thanks!!

        /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
    public string agencyId
    {
        get {
            return this.agencyIdField;
        }
        set {
            this.agencyIdField = value;
            this.RaisePropertyChanged("agencyId");
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool agencyIdSpecified
    {
        get
        {
            return this.agencyIdFieldSpecified;
        }
        set
        {
            this.agencyIdFieldSpecified = value;
            this.RaisePropertyChanged("agencyIdSpecified");
        }
    }
A: 

The purpose of XmlIgnoreAttribute is to tell the XmlSerializer that you don't want to serialize that property: it's the whole point. So what you're seeing is the designed behavior of that code. A much better question would be why the class implementor chose to decorate that property in that way.

Joel Coehoorn
I think the oddity is that the agenecyId was being ignored when the XmlIgnore attribute is on the agencyIdSpecified field.
workmad3
Ah: I mis-read the question. Good eye.
Joel Coehoorn
+5  A: 

There is a pattern (for XmlSerializer), that a property Foo will also look for either "bool FooSpecified", or "bool ShouldSerializeFoo()" - and if found, only serialize Foo if this other member returns true. So I assume that agencyIdSpecified had never been set to true? Removing this member would make it always serialize (unless you add a [DefaultValue] or similar).

This type of behaviour is used to model optional values on the occasion that we really need to know whether it was in the original data - i.e. does it have the value 0 because the caller told us that number, or because that is simply the default.

Note that the "FooSpecified" member commonly has [XmlIgnore] so that XmlSerializer knows that it shouldn't be considered as data for serialization. This isn't necessary (or legal, in fact) with "ShouldSerializeFoo()", since methods are never serialized.

Marc Gravell