代码之家  ›  专栏  ›  技术社区  ›  JL. Hans Passant

如何将异常对象序列化为XML字符串

  •  2
  • JL. Hans Passant  · 技术社区  · 15 年前

    我想要类似的东西

    try
     {
       //code here
     }
     catch (Exception ex)
      {
        stringXML = Exception.toXML(); 
      }
    

    这样,StringXML的值将是

     <exception><message></message><innerException></innerException></exception>
    

    例如。。。

    这怎么可能?

    2 回复  |  直到 11 年前
        1
  •  9
  •   Marc Gravell    15 年前

    这取决于你想写多少代码。一个简单的方法是编写自己的对象并使用 XmlSerializer :

    [XmlRoot("exception"), XmLType("exception")]
    public class SerializableException {
        [XmlElement("message")]
        public string Message {get;set;}
    
        [XmlElement("innerException")]
        public SerializableException InnerException {get;set;}
    }
    

    只需将一个常规的异常映射到这里。但因为这很简单,也许吧 XmlWriter 足够好了…

    public static string GetXmlString(this Exception exception)
    {
        if (exception == null) throw new ArgumentNullException("exception");
        StringWriter sw = new StringWriter();
        using (XmlWriter xw = XmlWriter.Create(sw))
        {
            WriteException(xw, "exception", exception);
        }
        return sw.ToString();
    }
    static void WriteException(XmlWriter writer, string name, Exception exception)
    {
        if (exception == null) return;
        writer.WriteStartElement(name);
        writer.WriteElementString("message", exception.Message);
        writer.WriteElementString("source", exception.Source);
        WriteException(writer, "innerException", exception.InnerException);
        writer.WriteEndElement();
    }
    
        2
  •  4
  •   Shay Erlichmen    14 年前

    已经有人 wrote a blog entry about it

    using System;  
    using System.Collections;  
    using System.Linq;  
    using System.Xml.Linq;  
    
    /// <summary>Represent an Exception as XML data.</summary>  
    public class ExceptionXElement : XElement  
    {  
        /// <summary>Create an instance of ExceptionXElement.</summary>  
        /// <param name="exception">The Exception to serialize.</param>  
        public ExceptionXElement(Exception exception)  
            : this(exception, false)  
        { }  
    
        /// <summary>Create an instance of ExceptionXElement.</summary>  
        /// <param name="exception">The Exception to serialize.</param>  
        /// <param name="omitStackTrace">  
        /// Whether or not to serialize the Exception.StackTrace member  
        /// if it's not null.  
        /// </param>  
        public ExceptionXElement(Exception exception, bool omitStackTrace)  
            : base(new Func<XElement>(() =>  
            {  
                // Validate arguments  
    
                if (exception == null)  
                {  
                    throw new ArgumentNullException("exception");  
                }  
    
                // The root element is the Exception's type  
    
                XElement root = new XElement  
                    (exception.GetType().ToString());  
    
                if (exception.Message != null)  
                {  
                    root.Add(new XElement("Message", exception.Message));  
                }  
    
                // StackTrace can be null, e.g.:  
                // new ExceptionAsXml(new Exception())  
    
                if (!omitStackTrace && exception.StackTrace != null)  
                {  
                    root.Add  
                    (  
                        new XElement("StackTrace",  
                            from frame in exception.StackTrace.Split('\n')  
                            let prettierFrame = frame.Substring(6).Trim()  
                            select new XElement("Frame", prettierFrame))  
                    );  
                }  
    
                // Data is never null; it's empty if there is no data  
    
                if (exception.Data.Count > 0)  
                {  
                    root.Add  
                    (  
                        new XElement("Data",  
                            from entry in  
                                exception.Data.Cast<DictionaryEntry>()  
                            let key = entry.Key.ToString()  
                            let value = (entry.Value == null) ?  
                                "null" : entry.Value.ToString()  
                            select new XElement(key, value))  
                    );  
                }  
    
                // Add the InnerException if it exists  
    
                if (exception.InnerException != null)  
                {  
                    root.Add  
                    (  
                        new ExceptionXElement  
                            (exception.InnerException, omitStackTrace)  
                    );  
                }  
    
                return root;  
            })())  
        { }  
    }