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

时间:2011-05-27 00:25:38

标签: c# .net json serialization json.net

我想知道如何使用Json.NET库排除/删除给定类型(或其集合)的某些属性被序列化? 我试着编写自己的合约解析器(继承自 DefaultContractResolver )但没有运气。

我知道我可以使用DataAnnotations完成,使用 ScriptIgnoreAttribute 装饰排除的属性,但在我的方案中它不适用。序列化的对象几乎可以是任何东西,因此我不知道在设计时要排除哪些属性。我只知道不应序列化的类型属性。

这看起来像一个相当简单的任务,但不幸的是我找不到合适的解决方案......

BTW - 我没有绑定Json.NET库 - 如果可以使用默认/其他.NET JSON序列化器轻松完成它对我来说同样是一个很好的解决方案

更新

在尝试序列化之前必须排除这些属性。为什么?

基本上,我正在接收和序列化的对象类型可以具有继承自 IDynamicMetaObjectProvider 的类型的动态属性。我不打算描述所有细节,但是从这些对象的 GetMetaObject 方法返回的 DynamicMetaObject 没有 DynamicMetaObject.GetDynamicMemberNames 方法已实现(抛出 NotImplementedException ...)。 总结 - 问题是那些对象(我需要排除)不允许枚举它们的属性,Json.NET序列化程序试图在幕后做什么。我最终总是抛出 NotImplementedException

3 个答案:

答案 0 :(得分:5)

我已尝试过WCF JSON序列化以及System.Web.Script.Serialization.JavaScriptSerializer。我发现如果你想要对序列化过程进行可靠的控制,并且不希望受到属性和黑客的约束,那么JavaScriptSerializer就是你要走的路。它包含在.NET堆栈中,允许您创建和注册JavaScriptConverter子类以执行类型的自定义序列化。

我发现可能导致问题的唯一限制是你不能轻易注册转换器来转换Object的所有子类(也就是说,一个转换器来统治它们)。您确实需要了解常见的基类,或者通过扫描程序集预先注册这组类型。但是,属性序列化完全取决于您,因此您可以决定使用简单的反射来序列化哪些属性以及如何。

另外,对于JSON,默认序列化要比WCF方法好得多。默认情况下,所有类型都是可序列化的,没有属性,枚举按名称序列化,字符串键字典序列化为JSON对象,列表序列化为数组等。但由于显而易见的原因,例如循环树,即使默认行为也需要时间的帮助时间。

在我的情况下,我支持的客户端API与服务器类结构不完全匹配,我们想要一个简单易用的JSON语法,JavaScriptSerializer每个人都做了诀窍时间。如果您需要一些代码示例,请告诉我。

答案 1 :(得分:2)

创建您自己的合约解析程序,覆盖为对象创建属性的方法,然后将结果过滤为仅包含您想要的那些。

答案 2 :(得分:-1)

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

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

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