簡體   English   中英

XmlSerializer.Deserialize為子類(不是數組)

[英]XmlSerializer.Deserialize for a sub class (not an array)

因此,這讓我感到迷惑了幾個小時……我有一個看起來像這樣的xml結構:

<custom>
  <priceLower>999999</priceLower>
  <priceUpper>1000001</priceUpper>
  <investment>true</investment>
  <offtheplan>false</offtheplan>
  <office>
    <name>Melbourne Office</name>
    <officeName>Head Office</officeName>
    ... more elements removed
  </office>
</custom>

在我的應用程序中,我有一個Custom類,該類從上面的xml fine反序列化,定義如下:

    [Serializable]
public class Custom : BaseEntity, IDataModel
{
    [XmlElement("investment")]
    public string Investment { get; set; }
    [XmlElement("offtheplan")]
    public string Offtheplan { get; set; }
    [XmlElement("priceLower")]
    public Decimal? PriceLower { get; set; }
    [XmlElement("priceUpper")]
    public Decimal? PriceUpper { get; set; }
    [XmlElement("office")]
    public Office Office { get; set; }

而我的Office對象定義如下:

    [Serializable]
public class Office : BaseEntity, IDataModel
{
    // temporary for debugging purposes:
    private string _officeName;

    [XmlElement("name")]
    public string Name { get; set; }
    [XmlElement("officeName")] 
    public string OfficeName { get; set; }
    [XmlElement("addressL1")]
    public string Address1 { get; set; }
    ... more fields removed }

反序列化代碼(由助手類調用,並接收包含一個Custom對象的屬性對象,其中Custom對象包含一個Office對象)如下所示:

            XmlSerializer s = null;
    XmlAttributeOverrides attrOverrides = null;

            /// if it's a Residential type, do it this way
            if (typeof(T) == typeof(Residential))
            {
                attrOverrides = new XmlAttributeOverrides();
                var attrs = new XmlAttributes();
                var attr = new XmlElementAttribute();
                attr.ElementName = "office";
                attr.Type = typeof(Office);
                attrs.XmlElements.Add(attr);
                attrOverrides.Add(typeof(Office), "office", attrs);
                s = new XmlSerializer(typeof(T), attrOverrides);
            }

            s = attrOverrides == null 
                ? new XmlSerializer(typeof(T)) 
                : new XmlSerializer(typeof(T), attrOverrides);

            var obj = s.Deserialize(stream);
            return (T)obj;

所以...自定義對象完全反序列化..那里沒有問題。 但是辦公場所卻沒有,它的所有屬性始終以null表示。

有沒有一種方法可以確切地指定xml樹中的哪個元素包含Office對象的數據? 我曾嘗試將Office對象移動到與Custom(位於Property對象上)相同的位置,這確實更有意義,但是那也不起作用-我將其移動到Custom下以匹配xml結構。不能改變它,我找不到一種方法來指定應該從哪里獲取數據。

我在這里經歷過的另一個怪異之處……我添加了一個Serializer函數,該函數基本上從反序列化的對象創建一個新的XML文件。 我可以一直調試直到調用Serialize函數的位置-如果在發生序列化的對象之前先對其進行窺視,我可以看到Office對象僅包含空值。 但是序列化程序實際上將數據序列化到我的新XML文件中。

這是更奇怪的地方。 如果在調用Serialize()之前先查看對象,則它將始終序列化一個空元素。 但是,如果在序列化發生之前我不偷看那個對象,它將把數據序列化到那里。 我已經多次驗證了這一點-毫無疑問,這就是行為。 有人看過這樣的東西嗎? 框架在欺騙我嗎?

更新:

為了澄清起見,我的XML看起來像這樣(上面我只顯示了作用):

<propertyList>
  <residential>
    <custom>
      <property1>
      <office>
        <officeName>
          Office Name Here
        </officeName>
      </office>
    </custom>
  </residential>
</propertyList>

因此,那里有一些嵌套級別,這可能是我所要解決的問題,盡管我認為這更多的是VS問題。

反序列化器正在處理完整的XML,並反序列化為這樣的類結構:

住宅:屬性:BasePropertyType

  • 包含自定義對象
  • 包含Office對象

自定義對象和辦公室對象都在住宅對象上實例化。 我嘗試將Office對象放到Custom對象上(以匹配xml結構),但這沒什么區別。 自定義正確序列化,Office不正確。

Visual Studio調試器是否完全有可能成為此處的紅色鯡魚。 如前所述,如果我調試並查看反序列化的對象,它將顯示為空,然后將其序列化回XML時,它將作為空。 但是,如果我不調試而只是不看對象就走了,那么所有屬性都會正確地序列化為XML。 當我無法調試正在發生的事情時,這將使繼續執行我需要進行的其余數據處理工作變得有些困難。 以前有人在VS中看到過這種行為嗎?

關於第一個問題, XmlSerializer可以處理簡單的層次結構,因此在您的示例中XmlAttributeOverrides是不必要的:

    [Serializable]
    [XmlRoot("custom")]
    public class Custom 
    {
        [XmlElement("investment")]
        public string Investment { get; set; }
        [XmlElement("offtheplan")]
        public string Offtheplan { get; set; }
        [XmlElement("priceLower")]
        public Decimal? PriceLower { get; set; }
        [XmlElement("priceUpper")]
        public Decimal? PriceUpper { get; set; }
        [XmlElement("office")]
        public Office Office { get; set; }
    }

    [Serializable]
    public class Office
    {
        // temporary for debugging purposes:
        private string _officeName;

        [XmlElement("name")]
        public string Name { get; set; }
        [XmlElement("officeName")]
        public string OfficeName { get; set; }
        [XmlElement("addressL1")]
        public string Address1 { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string xml = @"<custom>
  <priceLower>999999</priceLower>
  <priceUpper>1000001</priceUpper>
  <investment>true</investment>
  <offtheplan>false</offtheplan>
  <office>
    <name>Melbourne Office</name>
    <officeName>Head Office</officeName>
  </office>
</custom>";

            XmlSerializer s = new XmlSerializer(typeof(Custom));

            // Works fine without this
            //XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
            //var attrs = new XmlAttributes();
            //var attr = new XmlElementAttribute();
            //attr.ElementName = "office";
            //attr.Type = typeof(Office);
            //attrs.XmlElements.Add(attr);
            //attrOverrides.Add(typeof(Office), "office", attrs);
            //s = new XmlSerializer(typeof(Custom), attrOverrides);

            using (StringReader reader = new StringReader(xml))
            {
                Custom c = (Custom)s.Deserialize(reader);
            }
        }
    }

啊哈哈哈哈...我真是個蠢貨! 有一個同事陪伴着我,我們發現我做的事情確實很愚蠢,即:

public string ToString()
{
    Name = null;
    OfficeName = null;
    Address1 = null;
    Address2 = null;
    City = null;
    State = null;
    Postcode = null;
    Phone = null;
    Banner = null;
    Logo = null;

    StringBuilder sb = new StringBuilder();
    sb.Append(String.Format("Name:{0} / OfficeName: {1} / Address1: {2} / Address2: {3} / City: {4} / State: {5} / Postcode: {6} / Phone: {7} / Banner: {8} / Logo: {9}",
        Name, OfficeName, Address1, Address2, City, State, Postcode, Phone, Banner, Logo));
    return sb.ToString();
}

因此,每次我在調試器中查看對象時,它都在調用我的ToString()覆蓋,然后覆蓋所有值。

我不覺得很討厭。 大聲笑

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM