反序列化有效但XMLArray缺少c#XMLSerialize

时间:2013-02-20 13:17:16

标签: c# .net xml-serialization dynamics-crm-2011 deserialization

使用XMLSerialize序列化/反序列化,使用c#桌面应用程序通过相同的.NET生成和加载XML。

可序列化的类结构很安静,所以我只选择了两个相关的类。

现在,当我反序列化时,除了映射消息(或消息,如组织中调用对象列表的方式)之外,所有内容都被加载。

有没有人对此行为有解释?

我们也非常感谢任何有关改进已经完成的提示或提示。

谢谢。

我有以下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>

现在可序列化类看起来如下:

[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
}

我使用反序列化,如下所示:

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 个答案:

答案 0 :(得分:1)

反序列化程序尝试填充列表返回public List<MappingMessage> Messages。为了使序列化程序调用setter,您必须将属性类型更改为不可变集合类型,例如MappingMessage[]

编辑:要看到这一点,您可以通过具有支持字段的属性替换实体自动属性,并在getter和setter中设置断点。你不应该只在吸气器中打破设定器。