c# - 反序列化 json 对象并将内部对象转换为字符串值?

标签 c# json.net

我有一个网络服务返回 json 数据。我无法控制服务器端生成的 json。

我像这样反序列化 json:

JsonConvert.DeserializeObject<OuterObject>(jsonString);

问题是嵌入了内部对象(还有更多嵌套的内部对象)。我没有兴趣在我的应用程序中对它们进行建模。

json 数据是这样的:

{ 
    id : "xyz",
    name : "Some Object",
    properties : {
        prop_1 : "foo",
        prop_2 : "bar"
    },
    inner_object : {
        id : "abc$1",
        name : "Inner Object Name",
        ....
        // a whole lot of stuff here
        // with more embedded objects
        ....
    }
}

我想将外部对象建模为一个简单的 POCO,其中内部对象仅由(字符串)id 引用,而不是对象引用。

public class Outer
{
    public String Id { get; internal set; }
    public String Name { get; internal set; }
    public Dictionary<String,String> Properties { get; internal set; }

    // Just keep the InnerObject Id, no real reference to an instance
    public String InnerObjectId { get; set; }
}

我想我可以编写一个 JsonOuterObject 版本,其中包含对 JsonInnerObject 的真实对象引用,并从那里构造我的真实 OuterObject,然后丢弃其他对象……但这太蹩脚了。 (我不想在这样的提交中看到我的名字)

所以我现在正在使用 Json.NET 的 IContractResolver(覆盖 DefaultContractResolver),但看起来我要花很长时间了。

我是否遗漏了一些明显的 Json.NET 功能来帮我解决这个问题?

或者也许一些指针 IContractResolver 的哪些方法在这里很有趣?

编辑:.NET 中的 POJO 是 POCO显然。

最佳答案

为外部类型创建自定义 JsonConverter 可以让您在反序列化对象时有很大的灵 active 。

这是相当多的工作,但值得付出努力。特别是如果您无法控制返回的 JSON 对象,并且希望在客户端应用程序中以不同方式对返回数据建模。

JsonConverter 实现的核心是覆盖 ReadJson 方法

public override object ReadJson(JsonReader reader,
                                Type objectType,
                                object existingValue,
                                JsonSerializer serializer)

JsonReader 是数据的标记化流。一个实现可以是这样的:

public override object ReadJson(JsonReader reader,
                                Type objectType,
                                object existingValue,
                                JsonSerializer serializer)
{
    var outer = new Outer()

    while (reader.TokenType != JsonToken.EndObject)
    {
        if (reader.TokenType == JsonToken.PropertyName)
        {
            var propertyName = reader.Value.ToString();
            reader.Read();

            switch (propertyName)
            {
                case "id":
                    outer.Id = serializer.Deserialize<String>(reader);
                    break;
                case "id":
                    outer.Properties = serializer.Deserialize<Dictionary<String,String>>(reader);
                    break;
                case "inner_object"
                    var inner = serializer.Deserialize<Inner>(reader);
                    outer.InnerObjectId = inner.Id;
                    break;
                [...more cases...]
                default:
                    serializer.Deserialize<object>(reader);
                    break;
                }
                reader.Read(); // consume tokens in reader
            }
        } else {
            // throw exception ?
        }
    }

    return outer;
}

您可以使用 JsonConverterAttribute 注释您的 Outer 对象或将转换器传递给 JsonConverter 类的(重载)Deserialize(String json, params JsonConverter[] converters) 方法

关于c# - 反序列化 json 对象并将内部对象转换为字符串值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7473871/

相关文章:

c# - 简化 JSON 对象反序列化

c# - 在 VisualStudio 中创建 IronPython 项目时出错; "Exception has been thrown by the target of an invocation."

c# - Resharper 链式方法调用缩进

c# - 使用 linq 将 json 字符串解析为对象

c# - 将 JSON 对象反序列化为嵌套的 C# 对象

c# - json.net 可枚举

c# - 当字符串长度大于 32768 个字符时,.net 序列化器反序列化失败

c# 如何将变量从方法传递到 main?

C# WinForm - 关闭主窗体时 EXE 不会终止

c# - 比较两个相同结构的任意 JToken-s