如何XML反序列化未知类型的对象?

时间:2009-10-13 06:46:46

标签: .net xml-serialization

我想用XmlSerializer将我的对象保存到硬盘(如缓存)。在这种情况下,我没有任何问题。

但是,当我想将此XML反序列化为对象时,我收到错误。有什么办法吗? 将XML反序列化为未知对象或我创建的对象?

5 个答案:

答案 0 :(得分:1)

.Net无法反序列化为未知对象。

要成功序列化/反序列化XML对象,该类必须具有默认构造函数。最好的方法是向我们显示确切的错误消息。你能这样做吗?

答案 1 :(得分:0)

为什么不首先序列化类的类型(System.Type类是Serializable)?

然后,您可以检查序列化的类型并创建正确的实例。

答案 2 :(得分:0)

假设C#

这是我的解决方案:只需将字符串保存到文本文件或任何您想命名的文件中即可。

用法:

var xmlString = XmlHelper.Serialize(myObject);
var myNewObject = XmlHelper.Deserialize<myObjectType>(xmlString);

这是班级:

public static class XmlHelper
    {
        /// <summary>
        /// Gets the XML from an object, used like: var test = this.Serialize(response); for troubleshooting.
        /// </summary>
        /// <param name="pObject">The object.</param>
        /// <returns></returns>
        public static string Serialize(object pObject)
        {
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(pObject.GetType());
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            serializer.Serialize(sw, pObject);
            return Beautify(sb.ToString());
        }

        /// <summary>
        /// Deserializes the specified input.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="input">The input.</param>
        /// <returns></returns>
        public static T Deserialize<T>(string input)
        where T : class
        {
            System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(T));

            using (StringReader sr = new StringReader(input))
                return (T)ser.Deserialize(sr);
        }

        /// <summary>
        /// Beautifies the specified XML stuff.
        /// </summary>
        /// <param name="xmlStuff">The XML stuff.</param>
        /// <returns></returns>
        public static string Beautify(string xmlStuff)
        {
            System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
            doc.LoadXml(xmlStuff);

            string strRetValue = null;
            System.Text.Encoding enc = System.Text.Encoding.UTF8;
            // enc = new System.Text.UTF8Encoding(false);

            System.Xml.XmlWriterSettings xmlWriterSettings = new System.Xml.XmlWriterSettings
            {
                Encoding = enc,
                Indent = true,
                IndentChars = "    ",
                NewLineChars = "\r\n",
                NewLineHandling = System.Xml.NewLineHandling.Replace,
                //xmlWriterSettings.OmitXmlDeclaration = true;
                ConformanceLevel = System.Xml.ConformanceLevel.Document
            };


            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(ms, xmlWriterSettings))
                {
                    doc.Save(writer);
                    writer.Flush();
                    ms.Flush();

                    writer.Close();
                } // End Using writer

                ms.Position = 0;
                using (System.IO.StreamReader sr = new System.IO.StreamReader(ms, enc))
                {
                    // Extract the text from the StreamReader.
                    strRetValue = sr.ReadToEnd();

                    sr.Close();
                } // End Using sr

                ms.Close();
            } // End Using ms


            /*
            System.Text.StringBuilder sb = new System.Text.StringBuilder(); // Always yields UTF-16, no matter the set encoding
            using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(sb, settings))
            {
                doc.Save(writer);
                writer.Close();
            } // End Using writer
            strRetValue = sb.ToString();
            sb.Length = 0;
            sb = null;
            */

            xmlWriterSettings = null;
            return strRetValue;
        } // End Function Beautify
    }

答案 3 :(得分:-1)

另一个更高效(比DOM或SAX)数据绑定方法更多的是article

答案 4 :(得分:-2)

您可以使用我的帖子中描述的SerializationHelper.DeSerializeNow: http://borismod.blogspot.com/2008/07/nunit-serialization-test.html

internal class SerializationHelper
{
  private static readonly string DefaultFilePath = "test.dat";

  internal static void SerializeNow(object c)
  {
    SerializeNow(c, DefaultFilePath);
  }

  internal static void SerializeNow(object c, string filepath)
  {
   FileInfo f = new FileInfo(filepath);
   using (Stream s = f.Open(FileMode.Create))
   {
      BinaryFormatter b = new BinaryFormatter();
    b.Serialize(s, c);
   }
  }

  internal static object DeSerializeNow()
  {
    return DeSerializeNow(DefaultFilePath);
  }

  internal static object DeSerializeNow(string filepath)
  {
    FileInfo f = new FileInfo(filepath);
    using (Stream s = f.Open(FileMode.Open))
    {
      BinaryFormatter b = new BinaryFormatter();
      return b.Deserialize(s);
    }
  }
}