C# 将对象序列化为XML文件会引发异常

C# 将对象序列化为XML文件会引发异常,c#,serialization,xml-serialization,inner-classes,xmlserializer,C#,Serialization,Xml Serialization,Inner Classes,Xmlserializer,我看了几个问题,但没有一个答案有用。 我尝试使用几个流对象(StreamWriter,FileStream)。 我试着使用XmlWriter,XmlSerializer等等 这是我的代码: namespace FacebookPlusPlus { internal static class AppConfig { public static string AccessToken { get { return s_Serial

我看了几个问题,但没有一个答案有用。 我尝试使用几个流对象(
StreamWriter
FileStream
)。 我试着使用
XmlWriter
XmlSerializer
等等

这是我的代码:

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
方法时,指定的第一个参数可能是问题的根本原因:

在xmlWriter参数中,指定从 抽象XmlWriter类。XmlTextWriter源于 XmlWriter

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

资料来源:

编辑:因为你已经尝试了上面的方法,但它对你的问题没有帮助,就像克里斯·辛克莱说的,试着获得内部异常。以下代码段可能会有所帮助:

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 );            
}

来源:

好的,我按照@dbc的建议做了,并将
AppConfig
公开,删除了它的静态属性并隐藏了它的命令。很好

我仍然对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");
        }

        ...
    }
}

您是否可以检查抛出的异常中是否存在任何
InnerException
错误?对于
XmlSerializer
,这些内部异常通常包含相关信息。这是
XmlSerializer
的已知错误/限制。看见解决方法是取消嵌套类或使用
DataContractSerializer
,或使外部类非静态,但使用引发异常的私有构造函数。@dbc,谢谢。看到我的回答了吗?他们表示他们尝试了
XmlWriter
,但没有成功。此外,
StreamWriter
是一个有效的输入,因为它继承了使用Oops的
TextWriter
。他们一开始就提到了。是的,我试过了。为什么将一个对象序列化为XML如此困难?似乎.NET应该处于正确的状态,只允许您将一些数据转换为字符串。谢谢@gmalla,解决了这个问题。