我有一个类(有属性和一些方法)
[DataContract]
public partial class AbstractApplicationCallDto
{
[IgnoreDataMember]
private Exception exception;
[DataMember]
private string exceptionString;
[DataMember]
private string sessionId = null;
[DataMember]
private MyType myType = null;
}
当我将IgnoreDataMember
添加到具有Exception类型的字段时,我可以毫无问题地为客户端生成代码。但是如果添加DataMember
,则不会生成任何内容。
为什么?如何将Exception
类型添加到DataContract
?
答案 0 :(得分:4)
这不是一个真正的答案,只是关于异常序列化的一些注释,我想要一些代码的额外空间......
您是否考虑过使用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
类型时,客户端生成工具无法生成任何内容的原因......是否会出错?它会生成任何代码吗?
答案 1 :(得分:1)
我也有这个问题;通过创建字段类型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;
}
}