JSON.NET - 在运行时排除特定类型的属性
我想知道如何使用 Json.NET 库排除/剥离给定类型(或这些类型的集合)的某些属性进行序列化? 我尝试编写自己的合约解析器(继承自 DefaultContractResolver),但没有成功。
我知道我可以使用 DataAnnotations 来完成,用 ScriptIgnoreAttribute 装饰排除的属性,但在我的场景中它不适用。序列化的对象几乎可以是任何东西,因此我不知道在设计时要排除哪些属性。我只知道不应序列化的属性的类型。
它看起来像是一个相当简单的任务,但不幸的是我在任何地方都找不到像样的解决方案...
顺便说一句 - 我没有绑定到 Json.NET 库 - 如果它可以很容易地使用默认/其他 .NET JSON 序列化程序完成,这对我来说是一个同样好的解决方案。
更新
在尝试序列化属性之前必须排除这些属性。 为什么?
基本上,我接收和序列化的对象类型可以具有从 IDynamicMetaObjectProvider 继承的类型的动态属性。我不会描述所有细节,但是从这些对象的 GetMetaObject 方法返回的 DynamicMetaObject 没有 DynamicMetaObject.GetDynamicMemberNames 方法已实现(抛出NotImplementedException...)。 总结 - 问题是那些对象(我需要排除)不允许枚举它们的属性,这是 Json.NET 序列化程序试图在幕后执行的操作。我总是以抛出 NotImplementedException 告终。
I'm wondering how to exclude/strip certain properties of given type(s) (or collections of those) from being serialized using Json.NET library?
I tried to write my own contract resolver (inheriting from DefaultContractResolver) with no luck.
I know that I could be done using DataAnnotations, decorating the excluded properties with ScriptIgnoreAttribute, but it's not applicable in my scenario. The objects serialized can be virtually anything, so I don't know which properties to exclude at design-time. I know only the types of properties that should not be serialized.
It looks like a rather simple task, but unfortunately I couldn't find a decent solution anywhere...
BTW - I'm not bound to Json.NET library - if it can easily be done with default/other .NET JSON serializers it'd be an equally good solution for me.
UPDATE
The properties has to be excluded before trying to serialize them. Why?
Basically, the types of objects I'm receiving and serializing can have dynamic properties of type inheriting from IDynamicMetaObjectProvider. I'm not going to describe all the details, but the DynamicMetaObject returned from GetMetaObject method of these objects doesn't have DynamicMetaObject.GetDynamicMemberNames method implemented (throws NotImplementedException...). Summarizing - the problem is those objects (I need to exclude) doesn't allow to enumerate their properties, what Json.NET serializer tries to do behind the scenes. I always end up with NotImplementedException being thrown.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我尝试过 WCF JSON 序列化以及 System.Web.Script.Serialization.JavaScriptSerializer。我发现,如果您想要对序列化过程进行可靠的控制,并且不想受属性和黑客的束缚来使事情正常进行,那么 JavaScriptSerializer 就是您的最佳选择。它包含在 .NET 堆栈中,允许您创建和注册
JavaScriptConverter
子类以执行类型的自定义序列化。我发现可能给您带来问题的唯一限制是您无法轻松注册一个转换器来转换
Object
的所有子类(又名,一个转换器来统治所有子类)。您确实需要了解公共基类或通过扫描程序集预先注册类型集。但是,属性序列化完全由您决定,因此您可以使用简单的反射来决定要序列化哪些属性以及如何序列化。另外,JSON 的默认序列化比 WCF 方法要好得多。默认情况下,所有类型都可以在没有属性的情况下序列化,枚举按名称序列化,字符串键字典序列化为 JSON 对象,列表序列化为数组等。但由于显而易见的原因,例如循环树,即使是默认行为也有时需要帮助时间。
就我而言,我支持的客户端 API 与服务器类结构并不完全匹配,并且我们想要一种更简单、更容易理解的 JSON 语法,而
JavaScriptSerializer
每次都能做到这一点。时间。如果您需要一些代码示例才能开始,请告诉我。I have tried both the WCF JSON serialization as well as the System.Web.Script.Serialization.JavaScriptSerializer. I have found if you want solid control of the serialization process and do not want to be bound by attributes and hacks to make things work, the
JavaScriptSerializer
is the way to go. It is included in the .NET stack and allows you to create and registerJavaScriptConverter
subclasses to perform custom serialization of types.The only restriction I have found that may cause you a problem is that you cannot easily register a converter to convert all subclasses of
Object
(aka, one converter to rule them all). You really need to have knowledge of common base classes or preregister the set of types up front by scanning an assembly. However, property serialization is entirely left up to you, so you can decide using simple reflection which properties to serialize and how.Plus, the default serialization is much much much better for JSON than the WCF approach. By default, all types are serializable without attributes, enums serialize by name, string-key dictionaries serialize as JSON objects, lists serialize as arrays, etc. But for obvious reasons, such as circular trees, even the default behavior needs assistance from time to time.
In my case, I was supporting a client-API that did not exactly match the server class structure, and we wanted a much simpler JSON syntax that was easy on the eyes, and the
JavaScriptSerializer
did the trick every time. Just let me know if you need some code samples to get started.创建您自己的契约解析器,重写为对象创建属性的方法,然后过滤结果以仅包含您想要的结果。
Create your own contract resolver, override the method that creates the properties for an object and then filter the results to only include those that you want.
您是否考虑过使用 ShouldSerialize 前缀属性以在运行时排除特定类型的属性?
Have you considered using the ShouldSerialize prefix property to exclude the property of your specific type at runtime?