将对象序列化到 XML 文件会引发异常

Serializing an object to XML file throws an exception

我查看了几个问题,但 none 的答案有帮助。 我尝试使用多个流对象(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

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

In the xmlWriter parameter, specify an object that derives from the abstract XmlWriter class. The XmlTextWriter derives from the XmlWriter.

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

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

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

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

好的,我按照@dbc 的建议做了 AppConfig public,删除了它的静态属性并隐藏了它的 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");
        }

        ...
    }
}