簡體   English   中英

我無法使用XmlSerializer序列化C#中的對象列表

[英]I can't serialize a list of objects in C# with XmlSerializer

我有一個許多測試工具的列表,接口IDoTest,我想存儲在一個文件中。 我也想從這個文件中讀取。

簡單地使用XmlSerializer將對象存儲在我的IDoTest列表中似乎很自然。 但是,當我這樣做時,我得到一個模糊的我很抱歉我不能在System.Xml.Serialization.TypeDesc.CheckSupported()附近做錯誤

XmlSerializer可以只做瑣碎的工作嗎? 或者我錯過了什么? 他們正在談論MSDN上的自定義序列化 這是我的簡化代碼示例。

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    public interface IDoTest
    {
        void DoTest();
        void Setup();
    }
    internal class TestDBConnection : IDoTest
    {
        public string DBName;
        public void DoTest()
        {
            Console.WriteLine("DoHardComplicated Test");
        }
        public void Setup()
        {
            Console.WriteLine("SetUpDBTest");
        }
    }
    internal class PingTest : IDoTest
    {
        public string ServerName;
        public void DoTest()
        {
            Console.WriteLine("MaybeDoAPing");
        }
        public void Setup()
        {
            Console.WriteLine("SetupAPingTest");
        }
    }     

    internal class Program
    {
        private static void Main(string[] args)
        {

            TestDBConnection Do1 = new TestDBConnection { DBName = "SQLDB" };
            PingTest Do2 = new PingTest { ServerName = "AccTestServ_5" };
            List<IDoTest> allTest = new List<IDoTest> { Do1, (Do2) };
            // Now I want to serialize my list. 
            // Its here where I get the error at allTest
            XmlSerializer x = new XmlSerializer(allTest.GetType());
            StreamWriter writer = new StreamWriter("mySerializedTestSuite.xml");
            x.Serialize(writer, allTest); 

        }
    }
}

XmlSerializer無法序列化interface ,並且通過擴展,它無法序列化某個接口的List<> 它只能序列化具體的對象類型。

假設您可能希望在某個時刻反序列化對象,如果它只輸出與該接口有關的信息,則無法保證存在所有必需的數據來重建原始對象。

如果您能夠使用抽象基類並明確提供可能出現在列表中的每種可能類型的對象,則此帖子顯示了一種潛在的解決方法。

我按照StriplingWarrior給出的鏈接找到了這個優秀的答案。 來自webturner的 https://stackoverflow.com/a/15089253/648076

我改變了他的實現,並創建了一個實現List和IXmlSerializable的類類ListOfToDo。 那很有效! 這是我改變的代碼。

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    public interface IDoTest
    {
        void DoTest();
        void Setup();
    }
    public class TestDBConnection : IDoTest
    {
        public string DBName;
        public void DoTest()
        {
            Console.WriteLine("DoHardComplicated Test");
        }
        public void Setup()
        {
            Console.WriteLine("SetUpDBTest");
        }
    }
    public class PingTest : IDoTest
    {
        public string ServerName;
        public void DoTest()
        {
            Console.WriteLine("MaybeDoAPing");
        }
        public void Setup()
        {
            Console.WriteLine("SetupAPingTest");
        }
    }

    public class ListOfToDo : List<IDoTest>, **IXmlSerializable**
    {    
        #region IXmlSerializable
        public XmlSchema GetSchema(){ return null; }

        public void ReadXml(XmlReader reader)

           {
               reader.ReadStartElement("ListOfToDo");
               while (reader.IsStartElement("IDoTest"))
            {
                Type type = Type.GetType(reader.GetAttribute("AssemblyQualifiedName"));
                XmlSerializer serial = new XmlSerializer(type);

                reader.ReadStartElement("IDoTest");
                this.Add((IDoTest)serial.Deserialize(reader));
                reader.ReadEndElement(); //IDoTest
            }
            reader.ReadEndElement(); //IDoTest
        }

        public void WriteXml(XmlWriter writer)
        {
            foreach (IDoTest test in this)
            {
                writer.WriteStartElement("IDoTest");
                writer.WriteAttributeString("AssemblyQualifiedName", test.GetType().AssemblyQualifiedName);
                XmlSerializer xmlSerializer = new XmlSerializer(test.GetType());
                xmlSerializer.Serialize(writer, test);
                writer.WriteEndElement();
            }
        }
         #endregion
    }

    internal class Program
    {
        private static void Main(string[] args)
        {

            TestDBConnection Do1 = new TestDBConnection { DBName = "SQLDB" };
            PingTest Do2 = new PingTest { ServerName = "AccTestServ_5" };
            ListOfToDo allTest = new ListOfToDo { Do1, (Do2) };

            // Now I want to serialize my list. 
            // Its here where I get the error at allTest
            XmlSerializer x = new XmlSerializer(allTest.GetType());
            StreamWriter writer = new StreamWriter("mySerializedTestSuite.xml");
            x.Serialize(writer, allTest); 
            writer.Flush();
            writer.Close();

            //Read it aka deserialize
            {
                var xmlSerializer = new XmlSerializer(typeof(ListOfToDo));
                var xmlReader = XmlReader.Create(new StreamReader("mySerializedTestSuite.xml"));
                ListOfToDo readWhatToTest = (ListOfToDo)xmlSerializer.Deserialize(xmlReader);
                xmlReader.Close();
            }


        }
    }
}

輸出將是:

    <?xml version="1.0" encoding="utf-8"?>
<ListOfToDo>
  <IDoTest AssemblyQualifiedName="ConsoleApplication1.TestDBConnection, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <TestDBConnection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <DBName>SQLDB</DBName>
    </TestDBConnection>
  </IDoTest>
  <IDoTest AssemblyQualifiedName="ConsoleApplication1.PingTest, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <PingTest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <ServerName>AccTestServ_5</ServerName>
    </PingTest>
  </IDoTest>
</ListOfToDo>

不確定這可能是您的問題的原因,但在這兩個示例中,他們確實使用typeof(T)而不是T.GetType()

http://msdn.microsoft.com/en-us/library/71s92ee1.aspx

我無法使用XmlSerializer序列化C#中的對象列表

暫無
暫無

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

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