3

假设这个简单的场景:我的客户有一个已经在工作的 .net 应用程序,他/她想通过 WCF 公开一些功能。所以他给了我一个程序集,其中包含一个公开了 followig 方法的公共类。

OrderDetail GetOrderDetail (int orderId) // Suppose OrderDetail has {ProductId, Quantity, Amount)

现在,我希望 OrderDetail (Amount) 的某些成员不被序列化。根据http://msdn.microsoft.com/en-us/library/aa738737.aspx,执行此操作的方法是通过 [DataContract] 和 [DataMember]/[IgnoreDataMember] 属性。但是,这不是我的选择,因为我无法修改客户端的源代码。因此,我正在寻找一种方法来指定要在类型定义之外序列化的成员。应该是这样的:

    [OperationContract]
    [IgnoreMember(typeof(OrderDetail), "Amount" )]
    OrderDetail QueryOrder(int orderId){
          return OrderDetail.GetOrderDetail(orderId)  
    }

有什么办法吗?谢谢,伯纳贝

4

2 回答 2

4

不要通过网络发送客户端对象,而是从客户端对象创建一个 DTO,其中仅包含您要发送的信息,然后再发送该信息。

这使您可以准确控制要发送的信息,并且符合 WCF 传递消息而不是对象的意图

因此,创建一个并使用调用客户端代码中的方法返回OrderDetailDto class的数据填充它。使用和属性OrderDetail装饰 The (您可以在此处重命名类,以便当 WCF 返回它时返回 name )OrderDetailDtoDataContractDataMemberOrderDetail

对客户端代码中的所有对象重复此操作,以便在服务边界处您基本上从 DTO->Client 对象和 Client Objects->DTO 转换

编辑

虽然可能有一个选项允许您要求的内容(我不知道有一个,但希望其他人可能会)考虑当您发送使用您的客户端对象作为 DTO 时,您将它们用于两个目的(客户端对象和消息合同),这违反了单一责任原则,当您在客户端获得它们时,它们将不是相同的客户端对象,只是具有相同属性的 DTO,您将无法在客户端获得行为侧对象(至少在服务器端和客户端没有共享库的情况下不是这样)。

通过将数据契约绑定到对象,您最终还必须将客户端对象和数据契约的更改作为一件事来管理。当它们分开时,您可以管理对客户端对象的更改,而无需更改 DTO,您只需填充不同的内容。

虽然创建 DTO 似乎需要做很多工作,但最终我认为这是值得的。

于 2011-06-10T14:53:38.417 回答
1

您将不得不编写一个仅公开所需属性的包装类,并简单地调用您的客户端提供的类来获取其值。

唯一的其他选择是使用反射发出一个新的动态类并将其序列化(参见http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.aspx),但它可能不是除非您需要构建大量包装类,否则值得付出努力。

于 2011-06-10T14:57:47.667 回答