为了账号安全,请及时绑定邮箱和手机立即绑定

使自定义.NET Exception可序列化的正确方法是什么?

使自定义.NET Exception可序列化的正确方法是什么?

三国纷争 2019-10-23 14:23:31
更具体地说,当异常包含自定义对象时,自定义对象本身可以序列化也可以不序列化。举个例子:public class MyException : Exception{    private readonly string resourceName;    private readonly IList<string> validationErrors;    public MyException(string resourceName, IList<string> validationErrors)    {        this.resourceName = resourceName;        this.validationErrors = validationErrors;    }    public string ResourceName    {        get { return this.resourceName; }    }    public IList<string> ValidationErrors    {        get { return this.validationErrors; }    }}如果将此Exception序列化和反序列化,则将不保留两个自定义属性(ResourceName和ValidationErrors)。属性将返回null。是否存在用于实现自定义异常的序列化的通用代码模式?
查看完整描述

3 回答

?
波斯汪

TA贡献1811条经验 获得超4个赞

异常已经可以序列化,但是您需要重写该GetObjectData方法来存储变量并提供一个构造函数,该构造函数可在重新为对象补水时调用。


因此,您的示例变为:


[Serializable]

public class MyException : Exception

{

    private readonly string resourceName;

    private readonly IList<string> validationErrors;


    public MyException(string resourceName, IList<string> validationErrors)

    {

        this.resourceName = resourceName;

        this.validationErrors = validationErrors;

    }


    public string ResourceName

    {

        get { return this.resourceName; }

    }


    public IList<string> ValidationErrors

    {

        get { return this.validationErrors; }

    }


    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]

    protected MyException(SerializationInfo info, StreamingContext context) : base (info, context)

    {

        this.resourceName = info.GetString("MyException.ResourceName");

        this.validationErrors = info.GetValue("MyException.ValidationErrors", typeof(IList<string>));

    }


    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]

    public override void GetObjectData(SerializationInfo info, StreamingContext context)

    {

        base.GetObjectData(info, context);


        info.AddValue("MyException.ResourceName", this.ResourceName);


        // Note: if "List<T>" isn't serializable you may need to work out another

        //       method of adding your list, this is just for show...

        info.AddValue("MyException.ValidationErrors", this.ValidationErrors, typeof(IList<string>));

    }


}


查看完整回答
反对 回复 2019-10-23
?
BIG阳

TA贡献1859条经验 获得超6个赞

为了补充上面的正确答案,我发现如果将自定义属性存储在类的Data集合中,则可以避免执行此自定义序列化工作Exception。


例如:


[Serializable]

public class JsonReadException : Exception

{

    // ...


    public string JsonFilePath

    {

        get { return Data[@"_jsonFilePath"] as string; }

        private set { Data[@"_jsonFilePath"] = value; }

    }


    public string Json

    {

        get { return Data[@"_json"] as string; }

        private set { Data[@"_json"] = value; }

    }


    // ...

}

就性能而言,这可能比Daniel提供的解决方案效率低,并且可能仅适用于“整数”类型,例如字符串和整数等。


对于我来说,这仍然是非常容易并且可以理解的。


查看完整回答
反对 回复 2019-10-23
  • 3 回答
  • 0 关注
  • 641 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信