Eon
Eon

Reputation: 3974

XML Serialize Collections doesn't appear in XML

I am trying to serialize an class that inherits the interface ICollection as seen on this website, however, it is not appearing on my XML. What could possibly be wrong? Why isn't my XMLSerializer including the AssertionAttribute Collection? As for my examples, I apologize in advance for the ton of coding attached.

XML produced for this Element:

    <saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema" />

XML Expected to be produced from my example:

<saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="Language">
    <saml:AttributeValue xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">en-US</saml:AttributeValue>
  </saml:Attribute>
  <saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="fromApp">
    <saml:AttributeValue xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SP2</saml:AttributeValue>
  </saml:Attribute>
  <saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="Action">
    <saml:AttributeValue xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">VSREPORT</saml:AttributeValue>
  </saml:Attribute>
</saml:AttributeStatement>

Code:

AttributeStatement.cs

[Serializable]
[XmlType(Namespace="http://www.w3.org/2001/XMLSchema")]
public class AttributeStatement
{
    private static AssertionAttributes attributes = new AssertionAttributes();

    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();

    [XmlAttribute(AttributeName = "Attribute")]
    public static AssertionAttributes attribute;

    public AttributeStatement()
    {
        xmlns.Add("xs", "http://www.w3.org/2001/XMLSchema");
        SetAttributes();
    }

    private static void SetAttributes()
    {
        var languageAttribute = new AssertionAttribute("en-US");
        languageAttribute.Name = "Name";
        attributes.Add(languageAttribute);

        var fromAppAttribute = new AssertionAttribute("SP2");
        fromAppAttribute.Name = "fromApp";
        attributes.Add(fromAppAttribute);

        var actionAttribute = new AssertionAttribute("VSREPORT");
        actionAttribute.Name = "Action";
        attributes.Add(actionAttribute);

        attribute = attributes;
    }
}

AssertionAttributes.cs - The class should hold a collection of Type AssertionAttribute

[Serializable]
[XmlType(Namespace = "urn:oasis:names:tc:SAML:2.0:assertion")]
public class AssertionAttributes : ICollection
{
    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();

    public AssertionAttributes()
    {
        xmlns.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
    }

    private ArrayList empArray = new ArrayList();

    public AssertionAttribute this[int index]
    {
        get { return (AssertionAttribute)empArray[index]; }
    }

    void ICollection.CopyTo(Array array, int index)
    {
        empArray.CopyTo(array, index);
    }

    int ICollection.Count
    {
        get { return empArray.Count; }
    }

    bool ICollection.IsSynchronized
    {
        get { return false; }
    }

    object ICollection.SyncRoot
    {
        get { return this; }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return empArray.GetEnumerator();
    }

    public void Add(AssertionAttribute assertionAttribute)
    {
        empArray.Add(assertionAttribute);
    }
}

AssertionAttribute.cs - Should appear as multiple tags in xml (as produced)

[Serializable]
[XmlType(Namespace = "urn:oasis:names:tc:SAML:2.0:assertion")]
public class AssertionAttribute
{
    [XmlAttribute(AttributeName = "NameFormat")]
    public string NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:basic";

    [XmlElement(ElementName = "AttributeValue")]
    public AttributeValue attributeValue;

    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();

    public AssertionAttribute(string attributeValueText)
    {
        xmlns.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
        AttributeValueText = attributeValueText; 
        attributeValue = new AttributeValue(attributeValueText);
    }

    private string name;

    [XmlAttribute(AttributeName = "Name")]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private static string attributeValueText;

    public static string AttributeValueText
    {
        get { return attributeValueText; }
        set { attributeValueText = value; }
    }

}

AttributeValue.cs - An XML value simply to store a text value for this element

[Serializable]
[XmlType(Namespace="urn:oasis:names:tc:SAML:2.0:assertion")]
public class AttributeValue
{
    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();

    public AttributeValue(string attributeValueText)
    {
        xmlns.Add("saml", "urn.oasis:names:tc:SAML:2.0:assertion");
        Text = attributeValueText;
    }

    private string text;

    [XmlText]
    public string Text
    {
        get { return text; }
        set { text = value; }
    }

}

Upvotes: 1

Views: 289

Answers (1)

Reg Edit
Reg Edit

Reputation: 6914

By default during XML serialization, only the public properties and fields of an object are serialized. Your AssertionAttribute is a public field, so it should be serialized, right? Actually, no: note the word object :). Since AssertionAttribute is static, it's a field of the class, but not of objects of the class. If you can arrange things such as to remove the static modifier, that should do it.

Upvotes: 1

Related Questions