就像在主题中一样,我向一个端点发出请求,它返回给我一个json字符串。示例json字符串(选择了6个子字符串,还有大约1000个):
{"probability":0.0062596053,"tagId":"sometagid","tagName":"apple","boundingBox":{"left":0.27482307,"top":0.4361664,"width":0.14311266,"height":0.37521422}},
{"probability":0.0061301645,"tagId":"sometagid","tagName":"apple","boundingBox":{"left":0.0,"top":0.44423538,"width":0.09239961,"height":0.37426883}},
{"probability":0.0059485333,"tagId":"sometagid","tagName":"carrot","boundingBox":{"left":0.037714787,"top":0.0,"width":0.15685204,"height":0.27176687}},
{"probability":0.005887271,"tagId":"sometagid","tagName":"tomato","boundingBox":{"left":0.5249929,"top":0.70379305,"width":0.44499594,"height":0.29620594}},
{"probability":0.0057223,"tagId":"sometagid","tagName":"apple","boundingBox":{"left":0.79498,"top":0.34279144,"width":0.19351125,"height":0.39170527}},
{"probability":0.0056102676,"tagId":"sometagid","tagName":"apple","boundingBox":{"left":0.030394234,"top":0.21933028,"width":0.16375154,"height":0.3037323}},
我需要什么?我需要这个字符串被拆分成这6(+1000)个对象(最好是一个数组),我只想选择包含probability*100 > 50
的对象。
我已经创建了一个类,其中包含如下值:
public class ResponseJsonNode {
public double probability { get; set; }
public string tagId { get; set; }
public string tagName { get; set; }
public BoundingBox boundingBox { get; set; }
}
BoundingBox是另一个类:
public class BoundingBox {
double left { get; set; }
double top { get; set; }
double width { get; set; }
double height { get; set; }
}
可重复的例子(好不太真的,因为我不能张贴端点和键在这里):
using System.Net;
using System.Text.Json;
using ConsoleApp1;
WebRequest request = HttpWebRequest.Create("SomeUriEndpoint");
request.Method = "POST";
request.Headers.Add("some key", "some more key");
request.Headers.Add("some content type", "some more content type");
var f = File.Open(args[0], FileMode.Open);
using (var ms = new MemoryStream()) {
f.CopyTo(ms);
var fileBytes = ms.ToArray();
request.ContentLength = fileBytes.Length;
Stream stream = request.GetRequestStream();
stream.Write(fileBytes, 0, fileBytes.Length);
stream.Close();
//imageStringBase64 = Convert.ToBase64String(fileBytes);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
//JsonObject jo = (JsonObject)json;
List<ResponseJsonNode> jsonNodeList = JsonSerializer.Deserialize<List<ResponseJsonNode>>(json);
foreach(ResponseJsonNode rj in jsonNodeList) {
Console.WriteLine(rj);
}
这给了我一个错误:
The JSON value could not be converted to System.Collections.Generic.List
这也行不通:
HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();
//JsonObject jo = (JsonObject)json;
//List<ResponseJsonNode> jsonNodeList = JsonSerializer.Deserialize<List<ResponseJsonNode>>(json);
JsonArray jsonArray = JsonNode.Parse(json).AsArray();
List<ResponseJsonNode> nodes = new List<ResponseJsonNode>();
foreach(JsonObject jo in jsonArray) {
nodes.Add(new ResponseJsonNode { probability = Convert.ToDouble(jo["probability"]), tagName = (string)jo["tagName"] });
}
var stats = new Dictionary<string, double>();
foreach (ResponseJsonNode rjn in nodes) {
if (rjn.probability * 100 > 50)
if (stats.ContainsKey(rjn.tagName)) {
stats[rjn.tagName]++;
} else {
stats[rjn.tagName] = 1;
}
}
引发错误:System.InvalidOperationException: The node must be of type 'JsonArray'
我尝试过用很多教程解析它,但是每一个都似乎过时了或者不起作用(上面的例子)。那么,将json字符串转换成可迭代的JsonObject的最佳解决方案是什么呢?(不是C#库中的JsonObject类,而是我可以迭代的东西)
2条答案
按热度按时间hc2pp10m1#
[根据上述意见中的说明进行更新。]
你显示的JSON不是数组。这就是为什么你不能将它反序列化为数组。它是一个对象,其中包含了一个数组。但是为了访问这个数组,你需要反序列化这个对象。
因此,反序列化对象。例如,使用此类:
您可以将对象反序列化到该类中:
基本上,你遇到的问题是理解一个对象和一个对象数组之间的区别,或者一个对象和一个对象的 * 属性 * 之间的区别。你需要理解你的数据结构,以便使用这些数据。
8mmmxcuj2#
如果你的json是字面上你所显示的,你需要对它做一点修改,然后以标准的方式反序列化。
反序列化,然后:
顺便说一句,C#命名约定建议在PascalCase中命名属性,对于从camelCase反序列化,只需使用
JsonSerializerDefaults.Web
选项。我只想挑选概率 *100〉50对象。
然后简单的LINQ过滤就出现了。