我有一个类,我们称它为Person
,它包含有关一个人的许多详细信息,并具有表示这些详细信息的许多属性和子类。
例如:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public Address HomeAddress { get; set; }
}
public class Address
{
public string StreetName { get; set;}
public string Town { get; set;}
public string City { get; set;}
public string Postcode { get; set;}
}
我需要将此数据转换为预定的固定结构的JSON文件。该文件的格式如下:
{
"People": [
{
"PersonId": "1",
"PersonFields": [
{
"Description": "string",
"Value": "string"
}
]
}
]
}
上面的JSON文件包含一个数组,该数组的元素是使用Person
对象中包含的详细信息填充的,每个人都有一个ID,然后每个人的详细信息(例如FirstName
,LastName
,PhoneNumber
,StreetName
,Town
,City
和Postcode
都作为单独的元素存储在{ {1}}数组,其中PersonFields
是属性名称,而Description
是该属性内保存的值。
因此本质上我需要能够将Value
对象转换为以下对象:
Person
我显然可以手动执行此操作,实例化每个{
"People": [
{
"PersonId": "1",
"PersonFields": [
{
"Description": "FirstName",
"Value": "John"
},
{
"Description": "LastName",
"Value": "Smith"
},
{
"Description": "PhoneNumber",
"Value": "0123456789"
},
{
"Description": "StreetName",
"Value": "Street"
},
{
"Description": "Town",
"Value": "Town"
},
{
"Description": "City",
"Value": "City"
},
{
"Description": "Postcode",
"Value": "AB1 2CD"
},
]
}
]
}
元素并设置描述和值,然后使用它们填充数组。但是,这似乎是解决问题的漫长而不必要的方法。我想象有一种更快,更编程的方式来实现我的最终JSON文件,但是我不确定这是什么。
答案 0 :(得分:1)
首先将根类和属性类的所有属性放在一个列表中。每个列表项都是一个匿名类,其中属性的字段为Property
,父属性的字段为Parent
,如果Property
来自根类,即{{1 }} Person
为空,对于Parent
中的所有属性,父级为Address
。
HomeAddress
遍历每个人,读取所有属性值,构造具有预期输出结构的匿名对象树,然后将其输入JSON.NET。
我假设var rootProps = typeof(Person).GetProperties();
var flattenedProperties = new[] { new { Parent = (PropertyInfo)null, Properties = rootProps.Where(p => p.PropertyType == typeof(string)).ToArray() } }
.Concat(rootProps.Where(p => p.PropertyType != typeof(string) && p.PropertyType.IsClass).Select(p => new { Parent = p, Properties = p.PropertyType.GetProperties() } ))
.SelectMany(x => x.Properties, (x, p) => new { x.Parent, Property = p })
.ToArray();
是您的persons
对象的列表。
Person
答案 1 :(得分:-1)
您可以使用Json.Net的LINQ-to-JSON API(JObjects)来执行所需的操作。将您的人员列表加载到JArray
中,然后像这样进行转换:
df1 <- structure(list(id = 1:4, name.america = c("a", NA, NA, "d"),
name.europe = c(NA, "b", NA, NA), name.asia = c(NA, NA, "c",
NA)), class = "data.frame", row.names = c(NA, -4L))