当前位置:  开发笔记 > 编程语言 > 正文

如何在C#中序列化Exception对象?

如何解决《如何在C#中序列化Exception对象?》经验,为你挑选了7个好方法。

我试图在C#中序列化Exception对象.但是,似乎不可能,因为Exception类没有标记为[Serializable].有办法解决这个问题吗?

如果在执行应用程序期间出现问题,我希望被告知发生的异常.

我的第一反应是序列化它.



1> David Crow..:

使用[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) { }
}



2> davogones..:

我之前做过的是创建一个自定义的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;
    }
}


这样做的问题是,如果存在实际保存详细信息的内部异常,则不会包含此内容.

3> Rex M..:

Exception类标记为可序列化,并实现了ISerializable.请参阅MSDN:http://msdn.microsoft.com/en-us/library/system.exception.aspx

如果您尝试使用该序列化为XML XmlSerializer,则会对实现的任何成员发出错误IDictionary.这是XmlSerializer的限制,但该类肯定是可序列化的.



4> Antony Booth..:

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[] _Data; //This is the reason this class exists. Turning an IDictionary into a serializable object
    private string _HelpLink = string.Empty;
    private SerializableException _InnerException;
    private string _Message = string.Empty;
    private string _Source = string.Empty;
    private string _StackTrace = string.Empty;
    #endregion

    #region Constructors
    public SerializableException()
    {
    }

    public SerializableException( Exception exception ) : this()
    {
        setValues( exception );
    }
    #endregion

    #region Properties
    public string HelpLink { get { return _HelpLink; } set { _HelpLink = value; } }
    public string Message { get { return _Message; } set { _Message = value; } }
    public string Source { get { return _Source; } set { _Source = value; } }
    public string StackTrace { get { return _StackTrace; } set { _StackTrace = value; } }
    public SerializableException InnerException { get { return _InnerException; } set { _InnerException = value; } } // Allow null to be returned, so serialization doesn't cascade until an out of memory exception occurs
    public KeyValuePair[] Data { get { return _Data ?? new KeyValuePair[0]; } set { _Data = value; } }
    #endregion

    #region Private Methods
    private void setValues( Exception exception )
    {
        if ( null != exception )
        {
            _HelpLink = exception.HelpLink ?? string.Empty;
            _Message = exception.Message ?? string.Empty;
            _Source = exception.Source ?? string.Empty;
            _StackTrace = exception.StackTrace ?? string.Empty;
            setData( exception.Data );
            _InnerException = new SerializableException( exception.InnerException );
        }
    }

    private void setData( ICollection collection )
    {
        _Data = new KeyValuePair[0];

        if ( null != collection )
            collection.CopyTo( _Data, 0 );
    }
    #endregion
}


@AdamNaylor查看(例如)属性.我觉得最方便的只需要查看6行代码来查看所有属性,而不是(至少6x11 =)66行代码.你只是(就像我现在一样)表达"品味".因此,'Blurgh!'更多地说明了你表达自己的方式,然后它说明了正确的代码格式.但我想你已经意识到了......
按Ctrl + K,Ctrl + D,然后你可以停止抱怨换行.

5> mmr..:

如果您正在尝试序列化日志的异常,那么最好执行.ToString(),然后将其序列化到您的日志中.

但是这里有一篇关于如何做到的文章,以及为什么.基本上,您需要在异常上实现ISerializable.如果它是系统异常,我相信他们已经实现了该接口.如果它是别人的异常,您可以将其子类化以实现ISerializable接口.


所以现在,差不多两年后,我得到了一个downvote.关心解释,downvoter?
也许是因为文章链接坏了?

6> Tieson T...:

以防其他人偶然发现这个帖子(它是今天谷歌的第一页),这是一个非常有用的类,用于将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;
        })())
    { ; }
}



7> 小智..:

protected像这样创建一个构造函数(也应该标记你的Exception[Serializable]):

protected MyException(System.Runtime.Serialization.SerializationInfo info,
    System.Runtime.Serialization.StreamingContext context):base(info,context)
{
}

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有