使用 json.net/RestSharp 在 C# 中使用元数据反序列化 JSON
Deserialize JSON with metadata in C# using json.net/RestSharp
我正在尝试创建一个数据集,其中包含我从 API.
接收的 JSON 文件中的信息
当出现 "Unexpected JSON token when reading..." 时,我不断收到 JsonSerializationException。意外的标记是一些我似乎无法摆脱的元数据("paging" 等)。有没有一种方法可以忽略元数据,甚至根本不接收元数据?
Json 文件:
{
"paging": {
"size": 8
},
"data": {
"devices": [
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1301"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1299"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1296"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1291"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1261"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1249"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Up",
"worstState": "Down",
"name": "x",
"id": "157"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Up",
"worstState": "Down",
"name": "x",
"id": "205"
}
]
}
}
我的代码
//Following block (2) taken from Postman, looks for device down group using bearer token retreived from block (1)
var client2 = new RestClient("x");
client2.Timeout = -1;
var request2 = new RestRequest(Method.GET);
request2.AddHeader("Authorization", "bearer " + bearer.access_token);
IRestResponse response2 = client2.Execute(request2);
textBox1.Text = response2.Content;
//end of block (2)
//Deserialize dataset from downDevices
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(response2.Content);
DataTable dataTable = dataSet.Tables["devices"];
foreach (DataRow row in dataTable.Rows)
{
textBox1.AppendText(row["name"] + " - " + row["networkAddress"]);
}
到目前为止,我找到但未能尝试的唯一可能的解决方案是在 Newtonsoft 文档中:https://www.newtonsoft.com/json/help/html/DeserializeMetadataPropertyHandling.htm
但是,我不确定是否有办法将此对象与数据集结合使用。
object o = JsonConvert.DeserializeObject(response2.Content, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead //maybe use ignore?
});
//end of test Object
如果这是一个相当 basic/stupid 的问题或似乎重复出现,我深表歉意,我已经解决了尽可能多的类似问题并尝试了一些可能的解决方案,但无济于事。如果我的任何术语是 weird/wrong,我进一步道歉,我对 C# 和整个 API 是全新的。
提前致谢!
您的 JSON 无效:"networkAddress": "x,
,对象中缺少 "
id
1299
问题在于您尝试反序列化的方式。如果您只需要反序列化 Devices
对象,DataTable
反序列化就可以工作。但是加上Paging
(不是有效数据集)和Data
objs,你需要写一个自定义的class来反序列化这个obj并指向DataTable
。像这样:
public static void Deserialize()
{
string response2 = "{ \"paging\": { \"size\": 8 }, \"data\": { \"devices\": [ { \"hostName\": \"x\", \"networkAddress\": \"x\", \"bestState\": \"Down\", \"worstState\": \"Down\", \"name\": \"x\", \"id\": \"1301\" }] } } ";
var dataSet = JsonConvert.DeserializeObject<Target>(response2);
Console.WriteLine(dataSet);
DataTable dataTable = dataSet.data.devices;
Console.WriteLine(dataTable);
foreach(DataRow row in dataTable.Rows)
{
Console.WriteLine(row["hostname"]+" :name");
}
}
}
class Target
{
public object paging{get;set;}
public Device data{get;set;}
}
class Device
{
public DataTable devices {get;set;}
}
我正在尝试创建一个数据集,其中包含我从 API.
接收的 JSON 文件中的信息当出现 "Unexpected JSON token when reading..." 时,我不断收到 JsonSerializationException。意外的标记是一些我似乎无法摆脱的元数据("paging" 等)。有没有一种方法可以忽略元数据,甚至根本不接收元数据?
Json 文件:
{
"paging": {
"size": 8
},
"data": {
"devices": [
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1301"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1299"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1296"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1291"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1261"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Down",
"worstState": "Down",
"name": "x",
"id": "1249"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Up",
"worstState": "Down",
"name": "x",
"id": "157"
},
{
"hostName": "x",
"networkAddress": "x",
"bestState": "Up",
"worstState": "Down",
"name": "x",
"id": "205"
}
]
}
}
我的代码
//Following block (2) taken from Postman, looks for device down group using bearer token retreived from block (1)
var client2 = new RestClient("x");
client2.Timeout = -1;
var request2 = new RestRequest(Method.GET);
request2.AddHeader("Authorization", "bearer " + bearer.access_token);
IRestResponse response2 = client2.Execute(request2);
textBox1.Text = response2.Content;
//end of block (2)
//Deserialize dataset from downDevices
DataSet dataSet = JsonConvert.DeserializeObject<DataSet>(response2.Content);
DataTable dataTable = dataSet.Tables["devices"];
foreach (DataRow row in dataTable.Rows)
{
textBox1.AppendText(row["name"] + " - " + row["networkAddress"]);
}
到目前为止,我找到但未能尝试的唯一可能的解决方案是在 Newtonsoft 文档中:https://www.newtonsoft.com/json/help/html/DeserializeMetadataPropertyHandling.htm 但是,我不确定是否有办法将此对象与数据集结合使用。
object o = JsonConvert.DeserializeObject(response2.Content, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead //maybe use ignore?
});
//end of test Object
如果这是一个相当 basic/stupid 的问题或似乎重复出现,我深表歉意,我已经解决了尽可能多的类似问题并尝试了一些可能的解决方案,但无济于事。如果我的任何术语是 weird/wrong,我进一步道歉,我对 C# 和整个 API 是全新的。
提前致谢!
您的 JSON 无效:"networkAddress": "x,
,对象中缺少 "
id
1299
问题在于您尝试反序列化的方式。如果您只需要反序列化 Devices
对象,DataTable
反序列化就可以工作。但是加上Paging
(不是有效数据集)和Data
objs,你需要写一个自定义的class来反序列化这个obj并指向DataTable
。像这样:
public static void Deserialize()
{
string response2 = "{ \"paging\": { \"size\": 8 }, \"data\": { \"devices\": [ { \"hostName\": \"x\", \"networkAddress\": \"x\", \"bestState\": \"Down\", \"worstState\": \"Down\", \"name\": \"x\", \"id\": \"1301\" }] } } ";
var dataSet = JsonConvert.DeserializeObject<Target>(response2);
Console.WriteLine(dataSet);
DataTable dataTable = dataSet.data.devices;
Console.WriteLine(dataTable);
foreach(DataRow row in dataTable.Rows)
{
Console.WriteLine(row["hostname"]+" :name");
}
}
}
class Target
{
public object paging{get;set;}
public Device data{get;set;}
}
class Device
{
public DataTable devices {get;set;}
}