自定义JsonConverter不调用嵌套属性

时间:2019-03-12 10:32:00

标签: c# json json.net

我有一个Employee类,其中Manager属性本身是Employee

类型。
public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Employee Manager { get; set; }
    public IList<string> Roles { get; set; }
}

我想为Employee类型创建一个自定义JsonConverter。

public class TestJsonConverter : JsonConverter
{
    public TestJsonConverter()
    {
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);
        if (t.Type != JTokenType.Object)
        {
            t.WriteTo(writer);
        }
        else
        {
            JObject o = (JObject)t;
            IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList();
            o.AddFirst(new JProperty("Keys", new JArray(propertyNames)));
            o.WriteTo(writer);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Employee));
    }

    public override bool CanRead
    {
        get { return false; }
    }
}

ContractResolver是

class ContractResolver : DefaultContractResolver
{
    protected override JsonObjectContract CreateObjectContract(Type objectType)
    {
        JsonObjectContract contract = base.CreateObjectContract(objectType);
        if (objectType == typeof(Employee))
        {
            contract.Converter = new TestJsonConverter();
        }
        return contract;
    }
}

当我尝试序列化Employee对象时,自定义的JsonConverter仅针对顶级Employee对象而不是嵌套的Manager属性(也属于Employee类型)被调用

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new ContractResolver();
string json = JsonConvert.SerializeObject(employee, Formatting.Indented, settings);

1 个答案:

答案 0 :(得分:0)

因此JsonConverter从根节点开始运行一次。 您将需要浏览此JSon Object树并自行更新。

不确定这是您要实现的目标,但是我已经尝试过了,您可以决定是否对您有用。

public class TestJsonConverter : JsonConverter
{
    public TestJsonConverter()
    {
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);
        if (t.Type != JTokenType.Object)
        {
            t.WriteTo(writer);
        }
        else
        {
            JObject root = (JObject)t;
            var stack = new Stack<JObject>();
            stack.Push(root);
            while (stack.Any())
            {
                var current = stack.Pop();
                var propertyNames = current.Properties().Select(p => p.Name).ToArray();
                current.AddFirst(new JProperty("Keys", new JArray(propertyNames)));

                var nestedObjects = current.Properties().Where(p => p.Value.Type == JTokenType.Object).ToArray();
                foreach (var nestedObj in nestedObjects)
                {
                    stack.Push((JObject)nestedObj.Value);
                }
            }

            root.WriteTo(writer);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Employee));
    }

    public override bool CanRead
    {
        get { return false; }
    }
}