c# - 将具有嵌套属性的对象打印为逗号分隔的键值对字符串
问题描述
我有一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
)——我只关心所有的名称/值对。
所以最终结果将是一个Person
s 数组:
"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
. 即便如此,这看起来也不是最干净/最有效的方法。
解决方案
您可以使用这样的自定义来执行此操作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