错误序列化CLR对象以在WCF服务中使用

时间:2011-02-05 15:22:24

标签: c# wcf

我编写了一个自定义异常对象。原因是我想在发生错误时跟踪其他信息。我的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的恐惧。

非常感谢你的帮助!

2 个答案:

答案 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属性,序列化程序可能会充当字段序列化程序,这是您真正不想要的。