Mot*_*aTL 2 c# serialization json json.net
我从人口普查局的公共场所获得了一个不规则的JSON阵列.变量名都在第一个元素中,我无法反序列化它.
http://api.census.gov/data/2014/pep/agesex?get=AGE,POP,SEX&for=us:*&DATE=7
给我这样的JSON:
[["AGE","POP","SEX","DATE","us"],
["0","3948350","0","7","1"],
["1","3962123","0","7","1"],
["2","3957772","0","7","1"],
["3","4005190","0","7","1"],
["4","4003448","0","7","1"],
["5","4004858","0","7","1"],
["6","4134352","0","7","1"],
["7","4154000","0","7","1"]]
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法成功反序列化:
var test1 = JsonConvert.DeserializeObject<String[][]>(jsonStr);
Run Code Online (Sandbox Code Playgroud)
但是,我试图将它反序列化为这样的类:
public class TestClass
{
public string AGE { get; set; }
public string POP { get; set; }
public string SEX { get; set; }
public string DATE { get; set; }
public string us { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试这样做:
var test2 = JsonConvert.DeserializeObject<TestClass[]>(jsonStr);
Run Code Online (Sandbox Code Playgroud)
但我得到以下异常:
Newtonsoft.Json.dll中出现"Newtonsoft.Json.JsonSerializationException"类型的异常,但未在用户代码中处理
附加信息:无法创建和填充列表类型TestClass.路径'[0]',第1行,第2位.
小智 6
这有两个部分.
首先是将JSON转换为C#中可用的数据,第二个是将数据转换为漂亮的对象.
这是以下代码的dotNetFiddle.net工作示例:https://dotnetfiddle.net/Cr0aRL
JSON中的每一行都由一个字符串数组组成.所以这是一个字符串数组的数组.在C#中可以写成string [] [].
因此,要使用JSON.Net将JSON转换为可用数据,您可以执行以下操作:
var json = "[[\"AGE\",\"POP\",\"SEX\",\"DATE\",\"us\"],[\"0\",\"3948350\",\"0\",\"7\",\"1\"],[\"1\",\"3962123\",\"0\",\"7\",\"1\"],[\"2\",\"3957772\",\"0\",\"7\",\"1\"],[\"3\",\"4005190\",\"0\",\"7\",\"1\"],[\"4\",\"4003448\",\"0\",\"7\",\"1\"],[\"5\",\"4004858\",\"0\",\"7\",\"1\"],[\"6\",\"4134352\",\"0\",\"7\",\"1\"],[\"7\",\"4154000\",\"0\",\"7\",\"1\"]]";
var rawData = JsonConvert.DeserializeObject<string[][]>(json);
Run Code Online (Sandbox Code Playgroud)
接下来就是将数据转换为对象.
第一行是包含列名的标题,因此我们要抓取它,然后找出每个列名的列索引.
var headerRow = rawData.First();
var ageIndex = Array.IndexOf(headerRow, "AGE");
var popIndex = Array.IndexOf(headerRow, "POP");
var sexIndex = Array.IndexOf(headerRow, "SEX");
var dateIndex = Array.IndexOf(headerRow, "DATE");
var usIndex = Array.IndexOf(headerRow, "us");
Run Code Online (Sandbox Code Playgroud)
现在我们有索引,我们需要获取每一行,并将其转换为适当的对象.我已经使用了LINQ,因为它非常擅长以清晰的方式表示数据处理.
var testData = rawData
.Skip(1) //The first row is a header, not data
.Select(dataRow => new TestClass()
{
AGE = dataRow[ageIndex],
POP = dataRow[popIndex],
SEX = dataRow[sexIndex],
DATE = dataRow[dateIndex],
us = dataRow[usIndex]
});
Run Code Online (Sandbox Code Playgroud)
最后进行一些测试,以确保您拥有您期望的数据.
//Get the second data row as an example
var example = testData.Skip(1).First();
//Output example POP to check value
Console.WriteLine(example.POP);
Run Code Online (Sandbox Code Playgroud)
以上所有内容都非常手动.
你必须知道你的预期,您手动查找索引什么标题,然后手动行映射为对象.
一个简单的用例很可能这样做很好.但是在更大和/或更复杂的系统中,您可能需要/需要自动执行这些步骤.
自动执行这些步骤是可能的,但超出了本答案的范围,因为您如何处理它可能取决于许多不同的因素.
| 归档时间: |
|
| 查看次数: |
2217 次 |
| 最近记录: |