1

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

可序列化的类结构非常复杂,所以我只选择了两个相关的类。

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

有人对这种行为有解释吗?

任何改进已经完成的内容的提示或提示也总是值得赞赏的。

谢谢你。

我有以下 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);
                            }
                        }
                    }
                }
4

1 回答 1

1

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

编辑:要看到这一点,您可以将实体自动属性替换为具有支持字段的属性,并在 getter 和 setter 中设置断点。您不应该在 setter 中中断,而应该在 getter 中中断。

于 2013-02-20T15:20:12.787 回答