JSON.NET - 在运行时排除特定类型的属性

发布于 2024-11-10 00:02:01 字数 895 浏览 5 评论 0原文

我想知道如何使用 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 技术交流群。

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

发布评论

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

评论(3

乖乖公主 2024-11-17 00:02:01

我尝试过 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 register JavaScriptConverter 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.

慕烟庭风 2024-11-17 00:02:01

创建您自己的契约解析器,重写为对象创建属性的方法,然后过滤结果以仅包含您想要的结果。

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.

白日梦 2024-11-17 00:02:01

您是否考虑过使用 ShouldSerialize 前缀属性以在运行时排除特定类型的属性?

public class Employee
{
  public string Name { get; set; }
  public Employee Manager { get; set; }

  public bool ShouldSerializeManager()
  {
    return (Manager != this);
  }
}

Have you considered using the ShouldSerialize prefix property to exclude the property of your specific type at runtime?

public class Employee
{
  public string Name { get; set; }
  public Employee Manager { get; set; }

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