WCF序列化与对象继承?

时间:2009-03-18 14:02:01

标签: wcf .net-3.5 serialization

我有两个对象,一个在我们的企业级别,另一个在我们的服务级别。服务对象继承自企业。这是一个简单的例子:

[DataContract]
public class EnterpriseObject{
     [DataMember]
     int ID{get; set;}

     string InternalUse{get; set;}
}

[DataContract]
public class ServiceObject: EnterpriseBaseObject{
     [DataMember]     
     string Address{get; set;}
}

是否可以仅在序列化中公开ServiceObject(具有EnterpriseObject的继承属性)?我不希望客户端看到列为选项的企业对象?正如您在示例中所看到的,未为InternalUser属性设置DataMember属性。这是唯一的方法吗?感谢

2 个答案:

答案 0 :(得分:7)

您通过向[KnownType(typeof(ServiceObject))]添加EnterpriseBaseObject来处理继承 - 但是,EnterpriseBaseObject仍然是合同的一部分,并且它的存在将是公开的。但只有标记为[DataMember]的成员才会发布。

一个选项(删除继承)是为了序列化目的而有一个单独的DTO,并且在DTO版本和实际版本之间进行转换 - 但这会产生额外的工作。

答案 1 :(得分:2)

您可以将其从Is A模式更改为Has A模式吗?如果ServiceObject具有EnterpriseObject,则可以只公开所需的属性。

修改

如果我理解正确,您希望将ServiceObject公开给客户端,包括其所有属性(标记为DataMember),包括从EnterpriseObject继承的属性。但是您不希望客户端知道有一个名为EnterpriseObject的对象。

您可以通过隐藏存在企业对象的事实来实现此目的。而不是使用“是A”关系,这是一种继承模式。您可以使用合成或“有A”模式。

public class ServiceObject
{
   private EnterpriseObject _myEntObject;

   public string MyServiceObjectProperty
   {
      get;
      set;
   }

   public string MyEntObjectProperty
   {
     get { return _myEntObject.MyEntObjectProperty;}
   }
}

现在,您已将EnterpriseObject与客户端隔离开来。您的所有通信都是ServiceObject有一些您不向客户端公开的属性,这是由其他对象在服务器上实现的。

这也与拥有DTO相似,DTO的唯一目的是传输数据。 DTO允许您通过为客户提供他们所需格式的所需内容来隐藏您的实现,而不会暴露您的内部对象。