1

The XML is generated and loaded by the same .NET with c# desktop application using XMLSerialize serialization / deserialization.

The serializable class structur is quiet complex, so I just made a selection of the two relevant classes.

Now, when I deserialize, everything is loaded except the Mapping Messages (or Messages as how the object list is called in the Organization.

Does anyone have an explanation for this behaviour?

Any tips or hints for improving what has already been made are also always appreciated.

Thank you.

I have the following XML:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xsd="Company.Test3.Crm.Crm2Queue.Config.xsd">
    <organizations>
        <organization name="Vanilla">
            <settings>
                <ignoreemptyfields>true</ignoreemptyfields>
                <throwerroronmissingconfiguration>true</throwerroronmissingconfiguration>
            </settings>
            <endpoints>
                <endpoint>
                    <serviceUri>http://www.webservicex.net/usaddressverification.asmx</serviceUri>
                </endpoint>
            </endpoints>
            <messages>
                <message name="account">
                    <field name="accountnumber" mappedname="State" />
                    <field name="address1_county" mappedname="Zip" />
                    <field name="address1_latitude" mappedname="City" />
                </message>
            </messages>
            <entities>
                <entity name="account" messageschema="/XSD/.xsd" identifier="accountid">
                    <events>
                        <event name="create" message="" />
                        <event name="update" message="" />
                        <event name="delete" message="" />
                    </events>
                </entity>
            </entities>
        </organization>
    </organizations>
</configuration>

Now the serializable class looks as following:

[Serializable()]
public class Organization
{
    #region XmlIgnore

    [XmlIgnore()]
    public string Id { get; set; }

    [XmlIgnore()]
    public bool Checked { get; set; }

    [XmlIgnore()]
    public List<MappingMessage> mappingMessages { get; set; }

    #endregion

    #region Attributes

    [XmlAttribute("name")]
    public string Name { get; set; }

    #endregion

    #region Properties

    [XmlElement("settings")]
    public Settings Settings { get; set; }
    public bool ShouldSerializeSettings() { return (Settings != null && (Settings.IgnoreEmptyFields.HasValue || Settings.ThrowErrorOnMissingConfiguration.HasValue)); }

    [XmlArray("endpoints")]
    [XmlArrayItem("endpoint")]
    public List<Endpoint> Endpoints { get; set; }
    public bool ShouldSerializeignoreEndpoints() { return (Endpoints.Count > 0); }

    [XmlArray("messages")]
    [XmlArrayItem("message")]
    public List<MappingMessage> Messages 
    {
        get { return mappingMessages.Where(mm => (mm.Fields.Where(fi => !string.IsNullOrEmpty(fi.MappedName)).ToList().Count > 0)).ToList(); }
        set { mappingMessages = value; }
    }
    public bool ShouldSerializeFilledMappingMessages() { return (mappingMessages.Where(mm => (mm.Fields.Where(fi => !string.IsNullOrEmpty(fi.MappedName)).ToList().Count > 0)).ToList().Count > 0); }
    //public bool ShouldSerializeMappingMessages() { return (MappingMessages.Where(mm=> (mm.Fields.Where(fi=> !string.IsNullOrEmpty(fi.MappedName)).ToList().Count > 0)).ToList().Count > 0); }

    [XmlArray("entities")]
    [XmlArrayItem("entity")]
    public List<Entity> Entities { get; set; }
    public bool ShouldSerializeEntities() { return (Entities.Count > 0); }

    #endregion

    #region Constructors

    public Organization()
    {
        Settings = new Settings();
        Endpoints = new List<Endpoint>();
        mappingMessages = new List<MappingMessage>();
        Entities = new List<Entity>();
        Checked = false;
    }

    public Organization(string name)
        : this()
    {
        Name = name;
    }

    public Organization(string id, string name)
        : this(name)
    {
        Id = id;
    }

    #endregion
}


[Serializable()]
public class MappingMessage
{
    #region XmlIgnore

    [XmlIgnore()]
    public string EntityId { get; set; }


    [XmlIgnore()]
    public bool Checked { get; set; }

    [XmlIgnore()]
    public List<Field> Fields { get; set; }

    #endregion

    #region Attributes

    [XmlAttribute("id")]
    public string Id { get; set; }

    [XmlAttribute("name")]
    public string Name { get; set; }

    #endregion

    #region Properties

    [XmlElement("field")]
    public List<Field> SelectedFields
    {
        get
        {
            return Fields.Where(fi=> !string.IsNullOrEmpty(fi.MappedName)).ToList();
        }
        set
        {
            Fields = value;
        }
    }
    public bool ShouldSerializeSelectedFields() { return (SelectedFields.Count > 0); }

    [XmlElement("subentity")]
    public List<SubEntity> SubEntities { get; set; }
    public bool ShouldSerializeSubEntities() { return (SubEntities.Count > 0); }

    [XmlElement("parententity")]
    public List<ParentEntity> ParentEntities { get; set; }
    public bool ShouldSerializeParentEntities() { return (ParentEntities.Count > 0); }

    #endregion

    #region Constructors

    public MappingMessage()
    {
        Checked = false;
        Fields = new List<Field>();
        SubEntities = new List<SubEntity>();
        ParentEntities = new List<ParentEntity>();
    }

    public MappingMessage(string entityId)
        : this()
    {
        EntityId = entityId;
    }

    public MappingMessage(string entityId, string name)
        : this(entityId)
    {
        Name = name;
    }

    #endregion
}

And I use deserialization as shown below:

foreach (ZipEntry zipEntry in zipFile)
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        if (zipEntry.FileName.ToLower().EndsWith(".crm.crm2queue.config.xml"))
                        {
                            using (StreamReader streamReader = new StreamReader(memoryStream, Encoding.UTF8))
                            {
                                zipEntry.Extract(memoryStream);
                                memoryStream.Position = 0;
                                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Ciber.Crm.MappingCRMTo.Data.Configuration));
                                configuration = (Configuration)xmlSerializer.Deserialize(streamReader);
                            }
                        }
                    }
                }

1 Answer 1

1

The deserializer tries to fill the list returnepublic List<MappingMessage> Messages. In order to the serializer invoke the setter, you must change the property type to an immutable collection type, say MappingMessage[].

Edit : to see that, you can replace the Entities auto-property by a property with backing field, and set a breakpoint in both getter and setter. You should not break in the setter, only in the getter.

Sign up to request clarification or add additional context in comments.

1 Comment

I indeed already confirmed before that the setter is not called, which makes sense to me now. It works fine now, Thank you for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.