【问题标题】:WCF Serialization Information outside class definition类定义之外的 WCF 序列化信息
【发布时间】:2011-06-10 14:50:42
【问题描述】:

假设这个简单的场景: 我的客户有一个已经在工作的 .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)  
    }

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

【问题讨论】:

    标签: wcf datamember datacontracts


    【解决方案1】:

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

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

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

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

    编辑

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

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

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

    【讨论】:

    • Sam:这对于这个例子来说很好用,但在实际情况下,我有很多类,每个类同时具有一或两级层次结构,所以我最终会写很多 DTO 只是为了隐藏一些成员。我觉得你指出的关于暴露商业实体的内容很有趣,但是,只要我可以控制我暴露的内容,我觉得它没有那么糟糕。
    • @Bernabe,我补充了一些值得深思的东西。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-15
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-23
      • 2021-02-06
      • 1970-01-01
      相关资源
      最近更新 更多