【问题标题】:Serializing an object to XML file throws an exception [duplicate]将对象序列化为 XML 文件会引发异常 [重复]
【发布时间】:2015-11-06 22:00:31
【问题描述】:

我查看了几个问题,但没有一个答案有帮助。 我尝试使用几个流对象(StreamWriterFileStream)。 我尝试使用XmlWriterXmlSerializer 等。

这是我的代码:

namespace FacebookPlusPlus
{
    internal static class AppConfig
    {
        public static string AccessToken
        {
            get { return s_SerializableConfig.m_AccessToken; }
            set { s_SerializableConfig.m_AccessToken = value; }
        }

        public static bool AutoConnect
        {
            get { return s_SerializableConfig.m_AutoConnect; }
            set { s_SerializableConfig.m_AutoConnect = value; }
        }

        public static string ErrorMessage { get; set; }

        private const string k_ConfigFilePath = "AppConfig.xml";
        private static SerializableConfig s_SerializableConfig = new SerializableConfig();

        [Serializable]
        public class SerializableConfig
        {
            public string m_AccessToken;
            public bool m_AutoConnect;
        }

        public static bool ExportConfig()
        {
            bool exportSucceed = false;
            try
            {
                using (StreamWriter writer = new StreamWriter(File.Open(k_ConfigFilePath, FileMode.Create)))
                {
                    XmlSerializer serializer = new XmlSerializer(s_SerializableConfig.GetType());
                    serializer.Serialize(writer, s_SerializableConfig);
                }

                exportSucceed = true;
            }
            catch (Exception exception)
            {
                ErrorMessage = exception.Message;
                if (File.Exists(k_ConfigFilePath))
                {
                    File.Delete(k_ConfigFilePath);
                }
            }

            return exportSucceed;
        }

        public static bool ImportConfig()
        {
            bool importSucceed = false;
            if (File.Exists(k_ConfigFilePath))
            {
                try
                {
                    using (Stream stream = File.Open(k_ConfigFilePath, FileMode.Open))
                    {
                        XmlSerializer serializer = new XmlSerializer(s_SerializableConfig.GetType());
                        s_SerializableConfig = (SerializableConfig)serializer.Deserialize(stream);
                    }

                    importSucceed = true;
                }
                catch (Exception exception)
                {
                    importSucceed = false;
                    ErrorMessage = exception.Message;
                }
            }

            return importSucceed;
        }
    }
}

这是个例外:

There was an error generating the XML document.
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
   at FacebookPlusPlus.AppConfig.ExportConfig() in c:\\...\\AppLogic\\AppConfig.cs:line 48

发生错误时,字段AccessToken 包含一个长字符串,AutoConnect 包含true

【问题讨论】:

  • 你能检查出抛出异常中的任何InnerException 错误吗?使用XmlSerializer,那些内部异常通常包含相关信息。
  • 这是XmlSerializer 的一个已知错误/“限制”。见How to serialize non-static child class of static class。解决方法是取消嵌套嵌套类或使用DataContractSerializer,或使外部类非静态但使用引发异常的私有构造函数。
  • @dbc,谢谢。看我的回答

标签: c# serialization xml-serialization inner-classes xmlserializer


【解决方案1】:

好的,我按照@dbc 的建议将AppConfig 公开,删除了它的静态属性并隐藏了它的c'tor。效果很好!

仍然对 C# 奇怪的限制感到沮丧,这花了我几个小时才理解。而且我讨厌变通方法

namespace FacebookPlusPlus
{
    public class AppConfig
    {
        ...

        [Serializable]
        public class SerializableConfig
        {
            public string m_AccessToken;
            public bool m_AutoConnect;
        }

        private AppConfig() 
        {
            throw new InvalidOperationException("AppConfig Ctor Invoked");
        }

        ...
    }
}

【讨论】:

    【解决方案2】:

    当您调用Serealize 方法时,您指定的第一个参数可能是问题的根本原因:

    在 xmlWriter 参数中,指定一个从 抽象 XmlWriter 类。 XmlTextWriter 派生自 XmlWriter。

    在您的情况下,您使用的是不是 XmlWriter 的 StreamWriter。

    来源:https://msdn.microsoft.com/en-us/library/10y9yyta(v=VS.110).aspx

    编辑:由于您已经尝试了上述方法,但它对您的问题没有帮助,就像 Chris Sinclair 所说,尝试获取内部异常。以下代码 sn-p 可能会有所帮助:

    public void SerializeContainer( XmlWriter writer, Container obj )
    {
      try
      {
        // Make sure even the construsctor runs inside a
        // try-catch block
        XmlSerializer ser = new XmlSerializer( typeof(Container));
        ser.Serialize( writer, obj );
      }
      catch( Exception ex )               
      {                                   
        DumpException( ex );             
      }                                   
    }
    public static void DumpException( Exception ex )
    {
      Console.WriteLine( "--------- Outer Exception Data ---------" );        
      WriteExceptionInfo( ex );
      ex = ex.InnerException;                     
      if( null != ex )               
      {                                   
        Console.WriteLine( "--------- Inner Exception Data ---------" );                
        WriteExceptionInfo( ex.InnerException );    
        ex = ex.InnerException;
      }
    }
    public static void WriteExceptionInfo( Exception ex )
    {
      Console.WriteLine( "Message: {0}", ex.Message );                  
      Console.WriteLine( "Exception Type: {0}", ex.GetType().FullName );
      Console.WriteLine( "Source: {0}", ex.Source );                    
      Console.WriteLine( "StrackTrace: {0}", ex.StackTrace );           
      Console.WriteLine( "TargetSite: {0}", ex.TargetSite );            
    }
    

    来源:https://msdn.microsoft.com/en-us/library/Aa302290.aspx

    【讨论】:

    • 他们表示他们尝试了XmlWriter,但没有成功。此外,StreamWriter 是一个有效的输入,因为它继承自 TextWriter,与 this overload of Serialize. 一起使用
    • 糟糕。他们确实在一开始就提到了这一点。
    • 是的,我确实尝试过。为什么将对象序列化为 XML 如此困难?似乎 .NET 的心情应该不错,只是为了让您将一些数据转换为字符串。
    • 感谢@gmalla,解决了。
    猜你喜欢
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 2020-03-18
    • 2012-05-18
    • 2017-09-10
    • 1970-01-01
    • 2015-02-23
    相关资源
    最近更新 更多