包含异常的 DataContract

Posted

技术标签:

【中文标题】包含异常的 DataContract【英文标题】:DataContract which includes Exception 【发布时间】:2011-11-13 19:59:57 【问题描述】:

我有一个类(带有属性和一些方法)

[DataContract]
public partial class AbstractApplicationCallDto

    [IgnoreDataMember]
    private Exception exception;

    [DataMember]
    private string exceptionString;

    [DataMember]
    private string sessionId = null;

    [DataMember]
    private MyType myType = null;

当我将IgnoreDataMember 添加到异常类型的字段中时,我可以毫无问题地为客户端生成代码。但如果添加DataMember,则不会生成任何内容。

那为什么?如何将Exception 类型添加到DataContract

【问题讨论】:

当您将异常字段标记为 [DataMember] 时,请更清楚地解释问题。异常是可序列化的,所以它应该可以工作。 @Mark 异常被标记为可序列化。非 .net 客户端可以将它用于许多不同的事情,例如读取错误消息和堆栈跟踪。 虽然我建议在服务中捕获异常并抛出自定义的肥皂错误 (msdn.microsoft.com/en-us/library/ms733721.aspx)。序列化并返回发生的实际异常听起来不是一个好主意。安全方面就是这样。客户可能对您的实际实施了解得太多。 @Ben Exception 是可序列化的,但许多继承自 Exception 的类不是。如果将其设置为这些子类型之一,您可能会遇到问题。尝试返回异常时必须非常小心。 【参考方案1】:

这不是一个真正的答案,只是一些关于异常序列化的注释,我想要一些代码的额外空间......

您是否考虑过使用 FaultContracts 代替? http://msdn.microsoft.com/en-us/library/ms733721.aspx

虽然Exception 类型是可序列化的,但通常在其_data 字段中设置的任何内容都不可序列化,有时会导致序列化问题。 See here. 解决方法是在序列化之前将 _data 字段设置为 null:

        Exception ex = error;
        FieldInfo fieldInfo = typeof(Exception).GetField("_data", BindingFlags.Instance | BindingFlags.NonPublic);
        while (ex != null)
        
            fieldInfo.SetValue(ex, null);
            ex = ex.InnerException;
        

另一个问题是,通过将Exception 类型添加到DataContract,您只涵盖了实际Exception 实例的情况:

AbstractApplicationCallDto.Exception = new Exception();

但是,Exception 的任何派生词都不会起作用,例如:

AbstractApplicationCallDto.Exception = new NullReferenceException();

要完成这项工作,您必须将[KnownType] 属性添加到您的数据合同中,因此您最终会得到如下内容:

[DataContract]
[KnownType(typeof(NullReferenceException))]
[KnownType(typeof(InvalidOperationException))]
[KnownType(typeof(ApplicationException))]
[KnownType(typeof(...))] // add one for every type of exception you might need to serialize back, or that might be contained in Exception.InnerException
public partial class AbstractApplicationCallDto

    ...

回到你原来的问题,我想不出为什么当合同中有Exception 类型时客户端生成工具无法生成任何东西......它会给出错误吗?它会生成任何代码吗?

【讨论】:

好答案 - 你的最后一行应该是第一行。 好点。这只是我想到的最后一件事。我将对其进行编辑并将其移至顶部... 生成了一些代码,例如 AbstractApplicationCallDto、MyType 和一个类 Exception,但缺少服务接口代码。谢谢@ rally25rs,我会试试你的解决方案 @Pippl - 你可以为你的服务接口添加代码吗?由于它不在您的原始问题中,因此很难说为什么它可能不会生成。【参考方案2】:

我也有这个问题;我可以通过创建字段类型ExceptionDetail 并使用它来包装Exception 对象来绕过它。示例:

[DataContract]
public class WebServiceFault

    public WebServiceFault(Exception ex)
    
        Message = ex.Message;
        InnerException = new ExceptionDetail(ex);
    

    [DataMember]
    public string Message
    
        get;
        private set;
    

    [DataMember]
    public ExceptionDetail InnerException
    
        get;
        private set;
    

【讨论】:

什么是 ExceptionDetail ?

以上是关于包含异常的 DataContract的主要内容,如果未能解决你的问题,请参考以下文章

加载插件时,提示反射异常,调用的目标出现异常,该模块应包含一个程序集清单

UITableViewCell 曲线异常-左侧。这是啥原因造成的?包含图片

随机“CALayerInvalidGeometry 原因:CALayer 位置包含 NaN”异常

该列不能包含空值。 SqlCE 异常

未捕获的异常:CALayer 位置在做动画时包含 NaN

随机“CALayerInvalidGeometry原因:CALayer位置包含NaN”异常