我的JSON数据因帐户设置而异。它有一个“values”数组,可以包含零个或多个字段值数组,以及一个columnNames数组,它给出了与值一起使用的列名。这是一个例子:
{
"values": [
[
"32999000000001",
"32999*****0001",
"Joe",
"Doe",
"joe@doe.com",
"1/1/1900",
null,
"1234",
null,
"222-111-2223",
null,
null,
null,
null,
"UNITED STATES",
null,
null,
"Acme, Inc."
],
[
"39999000000002",
"39999*****0002",
"Joe",
"Schmoe",
"joe@yahoo.com",
"1/1/1990",
null,
"333-555-4444",
null,
"123 Some Street",
null,
"Michigan",
null,
null,
"UNITED STATES",
null,
null,
"Acme, Inc."
],
],
"columnNames": [
"accountNumber",
"Acct Number",
"First Name",
"Last Name",
"Email Address",
"Date Of Hire",
"Anniversary Date",
"Phone Number",
"Other Phone Number",
"Address1",
"Address2",
"City",
"State",
"Postal Code",
"Country",
"Company",
"Club ID",
"Member Type"
]
}
我需要使用此数据填充业务对象数组(业务对象具有我感兴趣的JSON数据中每个列名的属性):
public class SearchResultRecord
{
public string AccountNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public DateTime? DateOfHire { get; set; }
public DateTime? AnniversaryDate { get; set; }
public string PhoneNumber { get; set; }
public string OtherPhoneNumber { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string ClubId { get; set; }
public string MemberType { get; set; }
}
我打算为此使用JSON.NET,我可以创建一个自定义属性来装饰每个属性,然后使用反射来将值映射到正确的属性,但我希望有一个更容易/更清洁的方式或者可能已经内置到JSON.NET中的东西我可以使用。
什么是干净,好的方法来实现这一目标?
请注意,如果有更合适的库,我不使用JSON.NET。
答案 0 :(得分:1)
此代码将为您进行转换:
var props = typeof(SearchResultRecord).GetProperties().ToDictionary(
x => x.Name,
StringComparer.OrdinalIgnoreCase);
var jss = new JavaScriptSerializer();
var data = (Dictionary<string,object>)jss.DeserializeObject(json);
var cols = ((object[])data["columnNames"]).OfType<string>()
.Select((x,index) => new{index,name=x.Replace(" ","")})
.Where (x => props.ContainsKey(x.name))
.Select (x => new {x.index,prop=props[x.name]}).Dump();
var rows = ((object[])data["values"]).OfType<object[]>().ToArray();
foreach (var row in rows)
{
var rowdict = cols.Where (c => row[c.index] != null).ToDictionary(c => c.prop.Name, c => row[c.index]);
var rowjson = jss.Serialize(rowdict);
jss.Deserialize<SearchResultRecord>(rowjson).Dump();
}
答案 1 :(得分:0)
我发现你的JSON数据结构应该如下:
{ "values": [ [...], [...], ...], "columnNames": [...] }
因此,您必须创建包装SearchResultRecord的列表:
public class SearchResultRecord
{
// other entities here
...
// nested list used to hold jagged array values
public List<List<SearchResultRecord>> values { get; set; }
}
使用JavaScriptSerializer将锯齿状数组反序列化为预定义的通用列表:
Deserialize nested JSON array in C#
using System.Web.Script.Serialization;
SearchResultRecord model = new SearchResultRecord();
var result = new JavaScriptSerializer().Deserialize<List<List<SearchResultRecord>>>(jsonData);
model.values = result;
我建议您在反序列化过程中将列名声明(单个数组)与其值(锯齿状数组)分开,因为它们具有不同的数组大小和结构。