Search code examples
c#wcfxsdxml-deserialization

XmlChoiceIdentifier with mulitple namespaces


I'm working with the wonderful NIEM XML schemas. The the element I'm trying to deserialize has substitutions and extensions in other namespaces. I cannot figure out how to describe this in C#. I'm trying to deserialize a WCF message which contains an EntityPerson element from the urn:oasis:names:tc:legalxml-courtfiling:schema:xsd:CommonTypes-4.0 namespace in the Item property of this class.

Class Definition

[System.Xml.Serialization.XmlIncludeAttribute(typeof(ServiceRecipientType1))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(ServiceRecipientType))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CaseParticipantType1))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CaseAbstractorType))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.3752.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://niem.gov/niem/niem-core/2.0")]
public partial class EntityType : ComplexObjectType {
    
    private object itemField;
    
    private ItemChoiceType2 itemElementNameField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("EntityOrganization", typeof(OrganizationType), Namespace = "urn:oasis:names:tc:legalxml-courtfiling:schema:xsd:CommonTypes-4.0", IsNullable =true, Order=0)]
    [System.Xml.Serialization.XmlElementAttribute("EntityOrganizationReference", typeof(ReferenceType), Namespace = "http://niem.gov/niem/niem-core/2.0", Order =0)]
    [System.Xml.Serialization.XmlElementAttribute("EntityPerson", typeof(PersonType), Namespace = "http://niem.gov/niem/niem-core/2.0", IsNullable=true, Order=0)]
    [System.Xml.Serialization.XmlElementAttribute("EntityPerson", typeof(PersonType1), Namespace = "urn:oasis:names:tc:legalxml-courtfiling:schema:xsd:CommonTypes-4.0", IsNullable = true, Order = 0)]
    [System.Xml.Serialization.XmlElementAttribute("EntityPersonReference", typeof(ReferenceType), Namespace = "http://niem.gov/niem/niem-core/2.0",  Order =0)]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
    public object Item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
            this.RaisePropertyChanged("Item");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Order=1)]
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemChoiceType2 ItemElementName {
        get {
            return this.itemElementNameField;
        }
        set {
            this.itemElementNameField = value;
            this.RaisePropertyChanged("ItemElementName");
        }
    }
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.3752.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema=false)]
public enum ItemChoiceType2 {
    
    /// <remarks/>
    EntityOrganization,
    
    /// <remarks/>
    EntityOrganizationReference,
    
    /// <remarks/>
    EntityPerson,
    
    /// <remarks/>
    EntityPersonReference,
}

Any combination of Namespace parameters in the XmlElementAttributes just results in exceptions like below. If I remove the Namespace parameters then the Item property is null when deserialized.

System.InvalidOperationException: 'There was an error reflecting type 'MetadataType'.' InvalidOperationException: Type ItemChoiceType2 is missing enumeration value 'urn:oasis:names:tc:legalxml-courtfiling:schema:xsd:CommonTypes-4.0:EntityOrganization' for element 'EntityOrganization' from namespace 'urn:oasis:names:tc:legalxml-courtfiling:schema:xsd:CommonTypes-4.0'.

I need it to use the namespaces I define in the XmlElementAttributes but it seems when the deserializer tries to find the element name in the ItemChoiceType2 enum it wants to also match namespace. This doesn't work because the elements are in mulitple namespaces.

I read the documentation at https://it.ojp.gov/NISS/Downloads/KB/28 but it seems I have a problem not outlined in that documentation. (ItemChoice needed in different namespaces)

I've tried a million permutations of namespace parameters and I just can't find one that works. How do I define this property so that it can deserialize elements from multiple namespaces?


Solution

  • Ok so it turns out you can attribute the choice type enum with fully qualified names for the elements. This resolves the namespace errors.

        /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.3752.0")]
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema=false)]
    public enum ItemChoiceType2 {
        
        /// <remarks/>
        [System.Xml.Serialization.XmlEnum("urn:oasis:names:tc:legalxml-courtfiling:schema:xsd:CommonTypes-4.0:EntityOrganization")]
        EntityOrganization,
        
        /// <remarks/>
        EntityOrganizationReference,
    
        [System.Xml.Serialization.XmlEnum("http://niem.gov/niem/niem-core/2.0:EntityPerson")]
        EntityPerson,
    
        /// <remarks/>
        [System.Xml.Serialization.XmlEnum("urn:oasis:names:tc:legalxml-courtfiling:schema:xsd:CommonTypes-4.0:EntityPerson")]
        EntityPerson1,
        
        /// <remarks/>
        EntityPersonReference,
    }