我试图在C#中序列化Exception对象.但是,似乎不可能,因为Exception类没有标记为[Serializable]
.有办法解决这个问题吗?
如果在执行应用程序期间出现问题,我希望被告知发生的异常.
我的第一反应是序列化它.
使用[Serializable()]属性创建自定义Exception类.以下是从MSDN获取的示例:
[Serializable()] public class InvalidDepartmentException : System.Exception { public InvalidDepartmentException() { } public InvalidDepartmentException(string message) : base(message) { } public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { } // Constructor needed for serialization // when exception propagates from a remoting server to the client. protected InvalidDepartmentException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } }
我之前做过的是创建一个自定义的Error类.这封装了有关Exception的所有相关信息,并且是XML可序列化的.
[Serializable] public class Error { public DateTime TimeStamp { get; set; } public string Message { get; set; } public string StackTrace { get; set; } public Error() { this.TimeStamp = DateTime.Now; } public Error(string Message) : this() { this.Message = Message; } public Error(System.Exception ex) : this(ex.Message) { this.StackTrace = ex.StackTrace; } public override string ToString() { return this.Message + this.StackTrace; } }
Exception类被标记为可序列化,并实现了ISerializable.请参阅MSDN:http://msdn.microsoft.com/en-us/library/system.exception.aspx
如果您尝试使用该序列化为XML XmlSerializer
,则会对实现的任何成员发出错误IDictionary
.这是XmlSerializer的限制,但该类肯定是可序列化的.
mson写道:"我不确定你为什么要序列化异常..."
我将异常序列化,通过Web服务将异常冒泡到可以反序列化,然后重新抛出,记录或以其他方式处理它的调用对象.
我这样做了 我只是创建了一个Serializable包装类,用可序列化的替代方法替换IDictionary(KeyValuePair数组)
////// A wrapper class for serializing exceptions. /// [Serializable] [DesignerCategory( "code" )] [XmlType( AnonymousType = true, Namespace = "http://something" )] [XmlRootAttribute( Namespace = "http://something", IsNullable = false )] public class SerializableException { #region Members private KeyValuePair
如果您正在尝试序列化日志的异常,那么最好执行.ToString(),然后将其序列化到您的日志中.
但是这里有一篇关于如何做到的文章,以及为什么.基本上,您需要在异常上实现ISerializable.如果它是系统异常,我相信他们已经实现了该接口.如果它是别人的异常,您可以将其子类化以实现ISerializable接口.
以防其他人偶然发现这个帖子(它是今天谷歌的第一页),这是一个非常有用的类,用于将Exception
对象序列化为XElement
(yay,LINQ)对象:
http://seattlesoftware.wordpress.com/2008/08/22/serializing-exceptions-to-xml/
包含完整性的代码:
using System;
using System.Collections;
using System.Linq;
using System.Xml.Linq;
public class ExceptionXElement : XElement
{
public ExceptionXElement(Exception exception)
: this(exception, false)
{ ; }
public ExceptionXElement(Exception exception, bool omitStackTrace)
: base(new Func(() =>
{
// 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)
{
vroot.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()
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;
})())
{ ; }
}
protected
像这样创建一个构造函数(也应该标记你的Exception
类[Serializable]
):
protected MyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context):base(info,context) { }