有选择地将实例的属性序列化为 JSON

自由落体

我有一些包含某种奇怪格式的 JSON 文件。我必须为我的项目阅读、修改和保存这种格式。不幸的是,我对给定的格式没有任何影响。

这种格式的奇怪之处在于,这种结构中的所有实体都有一个唯一标识符,它(无效地)称为“$id”。这些实例也可以通过它们的 id 而不是它们的完整属性集来引用。在这种情况下,没有“$id”,而是有一个“$ref”字段,其中包含一个已定义的实体。看看下面的(缩短的)例子:

{
    "$id": "1",
    "StyleName": "Standard",
    "Style": {
        "$id": "2",
        "ShapeStyle": {
            "$id": "3",
            "Background": {
                "$id": "4",
                "Color": {
                    "$id": "5",
                    "A": 255,
                    "R": 68,
                    "G": 84,
                    "B": 106
                }
            }
        },
        "RightEndCapsStyle": {
            "$id": "6",
            "Background": {
                "$id": "7",
                "Color": {
                    "$ref": "5"
                }
            }
        }
    }
}

为了处理这个问题,我为所有 JSON 数据类创建了一个 C# 基类实体这个基类维护一个 id 注册表,以便它可以轻松找到给定$ref的实例这是代码:

public class Entity
{
    public static Dictionary<string, Entity> Registry = new Dictionary<string, Entity>();

    private string key = string.Empty;

    [JsonProperty("$id", Order = -2)]
    [DefaultValue("")]
    public string Key
    {
        get { return key; }
        set
        {
            key = value;
            if (!string.IsNullOrEmpty(key)) Registry.Add(key, this);
        }
    }

    [JsonProperty("$ref")]
    public string RefKey { get; set; }

    [JsonIgnore]
    public bool IsReference => !string.IsNullOrEmpty(RefKey);

    [JsonIgnore]
    public Entity RefEntity
    {
        get
        {
            Entity entity = null;
            if (IsReference && !Registry.TryGetValue(RefKey, out entity))
            {
                throw new ApplicationException("Referenced entity not found!");
            }
            return entity;
        }
    }
}

JSON 类层次结构如下所示:

public class RootObject: Entity
{
    public string StyleName { get; set; }
    public StyleRoot Style { get; set; }
}

public class StyleRoot: Entity
{
    public Style ShapeStyle { get; set; }
    public Style RightEndCapsStyle { get; set; }
}

public class Style: Entity
{
    public Background Background { get; set; }
}

public class Background: Entity
{
    public Color Color { get; set; }
}

public class Color: Entity
{
    public int A { get; set; }
    public int R { get; set; }
    public int G { get; set; }
    public int B { get; set; }
}

到现在为止还挺好。现在我的问题:

  1. [JsonProperty("$id")]并且[JsonProperty("$ref")]不起作用,因为$id$ref不是有效的 JSON 字段名称标识符。目前,我正在使用正则表达式将它们替换为有效的内容,然后将它们重新替换回原来的状态。但这是迟钝的。我想知道我是否可以使用NamingStrategy来实现相同的目标。但我没有成功。请记住,我需要两种方式,反序列化和序列化。
  2. 序列化是一个更难的问题。如果我按原样序列化我的结构,我最终会在每个实例中同时获得"$id":"$ref":字段。更重要的是,连同引用的项目,所有其他字段都使用默认值进行序列化。最简单的方法是简单地DefaultValueHandling.IgnoreAndPopulateJsonSerializerSettings. 但是这样,所有默认值都会从输出中删除,这会导致意外行为。我尝试使用 aContractResolver但失败了,因为这是当前属性的本地属性,无法将周围的实体考虑在内。还有其他方法可以实现自定义序列化策略吗?

棘手的问题,我知道。还有很多东西要阅读和理解。但如果这很容易,我就不会费力把它全部放在这里。迫切需要您的帮助。

德米特里·叶戈罗夫

模式启用时,这些$ids 和$refs 由 Json.NET 在内部使用你并不需要关心他们,只是定义等类,通常没有这种基础类和集的模式Json.NET 将处理引擎盖下s 和s 并创建一个保留原始引用结构的对象网络:PreserveReferencesHandlingRootObjectStyleRootEntityPreserveReferencesHandlingJsonSerializerSettings$id$ref

var obj = JsonConvert.DeserializeObject<RootObject>(json,
    new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });

序列化也可以在保留引用处理模式下完成:

var json = JsonConvert.SerializeObject(obj,
    new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });

演示:https : //dotnetfiddle.net/TygMDZ

注意在您的输入数据示例中,"$ref"属性包含一个数值,而 Json.NET 写入并期望"$ref"属性具有字符串值。可能是因为您在一些实验过程中不小心发布了更改的 JSON 文本?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将Java对象实例序列化为JSON

来自分类Dev

如何将JSON反序列化为具有HashMap属性的对象?

来自分类Dev

将Django queryset序列化为JSON:获取AttributeError'tuple'对象没有属性'_meta'

来自分类Dev

将 JSON 反序列化为具有列表属性的对象

来自分类Dev

将JSON反序列化为多个属性

来自分类Dev

将Json Property的属性反序列化为Property

来自分类Dev

将包含对象属性的poco序列化为Json

来自分类Dev

将JSON反序列化为通用接口属性

来自分类Dev

将json.net属性反序列化为大写

来自分类Dev

如何仅将更改的表单属性序列化为JSON

来自分类Dev

将JSON属性反序列化为类

来自分类Dev

如何将属性序列化为 json 对象?

来自分类Dev

ColdFusion不会将所有属性序列化为JSON

来自分类Dev

使用Jackson进行反序列化时有选择地忽略JSON属性

来自分类Dev

将JSON字段序列化为JSON

来自分类Dev

将具有不同格式的JSON字符串反序列化为同一Java类的实例

来自分类Dev

无法使用Json.Net将certian json属性反序列化为c#属性

来自分类Dev

JSON.NET:将json字符串属性序列化为json对象

来自分类Dev

将类类型序列化为JSON?

来自分类Dev

RESTKit将nil序列化为JSON

来自分类Dev

将[String:Any]序列化为JSON

来自分类Dev

将字典序列化为json文件

来自分类Dev

将多个类序列化为JSON

来自分类Dev

将JSON反序列化为子类

来自分类Dev

将类类型序列化为JSON?

来自分类Dev

Javascript将表格序列化为JSON

来自分类Dev

将元组序列化为 JSON

来自分类Dev

无法将字典序列化为 JSON

来自分类Dev

如何反序列化json数组,然后将普通属性反序列化为jackson中的pojo。单独的数组有效

Related 相关文章

热门标签

归档