类定义之外的 WCF 序列化信息

发布于 2024-11-14 18:50:26 字数 771 浏览 3 评论 0原文

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

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)  
    }

有什么办法做到这一点吗? 谢谢, 贝尔纳贝

Suppose this simple scenario:
My client has an already working .net application and he/she wants to expose some functionality through WCF. So he gives me an assembly, containg a public class that exposes the followig method.

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

Now, I want some members of OrderDetail (Amount) not to be serialized.
According to http://msdn.microsoft.com/en-us/library/aa738737.aspx, the way to do this is by means of the [DataContract] and [DataMember]/[IgnoreDataMember] attributes. However, that's not an option for me because I can not modify client's source code. So I'm looking for a way to specify which members I want to serialize out, outside the type's definition. Something that should look like this:

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

Is there any way to to this?
Thanks,
Bernabé

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

偏闹i 2024-11-21 18:50:26

不要通过线路发送客户端对象,而是从仅包含您要发送的信息的客户端对象创建 DTO,然后发送该信息。

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

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

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

EDIT

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

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

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

Don't send the clients objects across the wire, create a DTO from the clients object containing only the information that you want to send and send that instead.

This allows you to control exactly what information gets sent, and is in keeping with the WCF intentions of passing messages and not objects

So create an OrderDetailDto class and populate this with the data from the OrderDetail returned by the call to the method in the clients code. Decorate The OrderDetailDto with the DataContract and DataMember attributes (you can rename the class in here so that when it is returned by WCF it is returned with the name OrderDetail)

Repeat this for all objects in the client code, so that at the service boundary you basically convert from DTO->Client objects and Client Objects->DTO

EDIT

Whilst there might be an option which allows what you have asked for (I am not aware of one, but hopefully someone else might be) consider that when you send use your client objects as DTOs you are using them for two purposes (the client object and the message contract), which is against the Single Responsibility Principle and when you get them on the client side they will not be the same client side objects, just DTOs with the same properties, you will not be able to get behaviour in the client side objects (at least not without sharing libraries on the server side and client side).

By binding the data contract to the objects you also end up having to manage the changes to client objects and data contracts as one thing. When they are separate you can manage the changes to client side objects without neccessarily changing the DTOs, you can just populate the differently.

Whilst it seems like it is a lot of work to create the DTOs, in the end I think it will be worth it.

吻泪 2024-11-21 18:50:26

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

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

You will have to write a wrapper class that only exposes the desired properties and simply calls the class your client provided to gets its values.

The only other option would be to emit a new dynamic class using reflection and serialize that (see http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.aspx), but its probably not worth the effort unless you need to build a lot of wrapper classes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文