在某些应用程序中,允许 Web 端点的使用者在返回的对象图中指定他们想要的属性子集,根据请求进行自定义,这很方便。调用者将在查询字符串/请求中指出他们想要的属性。需要自定义每个请求的序列化,而不是每个类型结构。我想不出一个理想的方法来解决这个问题——理想情况下,它不强制对视图模型(要序列化的对象)进行任何更改,而只是为每个端点启用此功能(例如,通过在端点上放置一个属性)。
今天有一种方法可以做到这一点,例如在 MVC4/Web Api 中,但它并不理想。JSonPropery 上的 ShouldSerialize 谓词几乎是不需要更改任何视图模型所需的,除了回调只提供实例/对象而没有上下文(用户想要哪些属性,您在对象图中的位置)。如果您只对一种类型进行过滤就可以了,那么这将起作用(如果您使用请求全局 HttpContext),但这不适用于更通用的解决方案来进行分层过滤和/或当一个类型可以出现在多个级别中时对象图。
目前,我看到的一种方法是为要序列化的视图模型提供一个基类/接口,然后实现 ISerializable。您还必须编写自己的 MediaTypeFormatter 以便您可以将内容填充到流上下文中以完成过滤所需的工作,例如查询字符串中指定的字段以及访问具有方便 Path 属性的编写器可用于轻松地对属性名称进行分层和/或通配符过滤。
我看不到无需触摸视图模型对象的方法。我们需要在序列化程序中添加功能。一种方法是将流式上下文添加到 ShouldSerialize 回调签名中(可能需要在 JSonProperty 接口上使用新方法,除非可以选择指定传入的实例对象的格式也包含流式上下文)。添加按属性名称过滤的逻辑仍然是我们的工作。另一种方法是将逻辑烘焙到 JSonSerializerInternalWriter::ShouldSerialize 方法上,并在序列化设置中有条件地启用该功能。
关于如何在不接触视图模型的情况下执行此操作的任何其他想法?