我编写了一个自定义异常对象。原因是我想在发生错误时跟踪其他信息。我的CLR对象定义如下:
public class MyException : Exception
{
public override string StackTrace
{
get { return base.StackTrace; }
}
private readonly string stackTrace;
public override string Message
{
get { return base.Message; }
}
private readonly string message;
public string Element
{
get { return element; }
}
private readonly string element;
public string ErrorType
{
get { return errorType; }
}
private readonly string errorType;
public string Misc
{
get { return misc; }
}
private readonly string misc;
#endregion Properties
#region Constructors
public MyException()
{}
public MyException(string message) : base(message)
{ }
public MyException(string message, Exception inner) : base(message, inner)
{ }
public MyException(string message, string stackTrace) : base()
{
this.message = message;
this.stackTrace = stackTrace;
}
public MyException(string message, string stackTrace, string element, string errorType, string misc) : base()
{
this.message = message;
this.stackTrace = stackTrace;
this.element = element;
this.errorType = errorType;
this.misc = misc;
}
protected MyException(SerializationInfo info, StreamingContext context) : base(info, context)
{
element = info.GetString("element");
errorType = info.GetString("errorType");
misc = info.GetString("misc");
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("element", element);
info.AddValue("errorType", errorType);
info.AddValue("misc", misc);
}
}
我在WP7应用程序中创建了这个自定义xception的副本。唯一的区别是,我没有定义GetObjectData方法或定义了SerializationInfo的构造函数。如果我按原样运行应用程序,则会收到错误消息:
类型'My.MyException'无法序列化。请考虑使用DataContractAttribute属性对其进行标记,并使用DataMemberAttribute属性标记要序列化的所有成员。如果类型是集合,请考虑使用CollectionDataContractAttribute标记它。
如果我将DataContract / DataMember属性添加到服务器端的类及其相应的成员,我会收到一条错误消息: Type不能是ISerializable并且具有DataContractAttribute属性。
如何序列化MyException以便我可以将其实例传递给我的WCF服务。请注意,我想从Android应用程序中使用我的服务。因此,我不想做以微软为中心的任何事情。这是我对DataContract / DataMember的恐惧。
非常感谢你的帮助!
答案 0 :(得分:2)
您需要将[Serializable]
添加到自定义类。这是你的第一个错误最有可能告诉你的,这个东西需要是可序列化的,虽然它告诉你使用首选的WCF(使用DataContract)方式。
你不能混合序列化接口(DataContract和ISerializable),这是第二个错误告诉你的。 Exception
已经实现了ISerializable
,WCF将支持这一点。从您的代码看起来,您已经为此添加了一些方法(具有SerializationInfo
的方法)。
就像Marc所说的那样,使用DataContract的东西并没有以.NET为中心,它在客户端消费方面与平台无关。
答案 1 :(得分:0)
DataMember等没有任何可怕的结果;他们很好地转换为标准的SOAP概念。但例外情况:不那么严重。对于纯WCF,您应该考虑faults而不是原始异常,但在 general 情况下,我会返回(作为我的操作结果)一个对象,该对象可选地包含有关预期失败的信息。应该在服务器上留下意外的故障,并返回一般的“oops”结果。
例如,您可以简单地使用:
[DataContract]
public class FooResult {
[DataMember]
public string Error {get;set;}
[DataMember]
public SomeType Result {get;set;}
}
调用者应该期望Error
异或Result
。另请注意,如果没有DataContract / DataMember属性,序列化程序可能会充当字段序列化程序,这是您真正不想要的。