首页 > 解决方案 > 将具有嵌套属性的对象打印为逗号分隔的键值对字符串

问题描述

我有一Person堂课:

public class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
}

作为最终结果,我想将一个Person实例打印为 JSON,但我希望它是一个巨大的键值对字符串,例如:

"Name:John,Surname:Doe,Line1:Infinite Loop,Line2:California"

请注意,在上面的示例中,我去掉了实际的类名(即打印出来Line1而不是Address.Line1)——我只关心所有的名称/值对。

所以最终结果将是一个Persons 数组:

"persons":[
    "Name:John,Surname:Doe,Line1:Infinite Loop 1,Line2:California",            
    "Name:Jane,Surname:Doe,Line1:Infinite Loop 2,Line2:California"
]

作为起点,我尝试使用反射:

void Main()
{
    var persons = new List<Person>();
    persons.Add(new Person
    {
        Name = "John",
        Surname = "Doe",
        Address = new Address
        {
            Line1 = "Infinite Loop",
            Line2 = "California"                
        }
    });

    foreach(var person in persons)
    {
        var properties = new List<string>();
        foreach(var property in person.GetType().GetProperties())
        {
            properties.Add($"{property.Name}:{property.GetValue(person, null)}");
        }
        Console.WriteLine(string.Join(",", properties));
    }
}

但我在 LINQPad 中得到以下输出:

Name:John,Surname:Doe,Address:UserQuery+Address

我假设Address没有正确迭代,因为它是Person. 即便如此,这看起来也不是最干净/最有效的方法。

标签: c#.netreflectionjson.net

解决方案


您可以使用这样的自定义来执行此操作JsonConverter

class PersonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Person);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var pairs = JObject.FromObject(value)
            .Descendants()
            .OfType<JProperty>()
            .Where(p => p.Value is JValue)
            .Select(p => p.Name + ":" + p.Value);
        writer.WriteValue(string.Join(",", pairs));
    }

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后通过将转换器传递给它来使用它JsonConvert.SerializeObject

string json = JsonConvert.SerializeObject(obj, Formatting.Indented, new PersonConverter());

这是一个工作演示:https ://dotnetfiddle.net/L4YDsm


推荐阅读