【问题标题】:How do I convert json string into JsonObject and iterate on it? .NET Core 6.0 c#如何将 json 字符串转换为 JsonObject 并对其进行迭代? .NET 核心 6.0 C#
【发布时间】:2022-11-28 22:26:04
【问题描述】:

正如在主题中一样,我正在向端点发出请求,端点作为回报给我一个 json 字符串。示例 json 字符串:

{"probability":0.0052179075,"tagId":"someTagId","tagName":"lemon","boundingBox":{"left":0.66796285,"top":0.6232077,"width":0.16709894,"height":0.34347737}},

我已经制作了一个包含以下值的类:

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 类,而是我可以迭代的东西)

【问题讨论】:

  • 您显示的 JSON 是单个对象,而不是数组。你为什么要把它变成List&lt;ResponseJsonNode&gt;?这样做的目标是什么?
  • 是的,我可能误解了这个类的使用。我希望将这个名为 string json 的特定 json 字符串放入数组中,这样我就可以轻松地只获取包含概率超过 50% 的 tagName 的字段。
  • 好吧,如果你真的想要一个数组,那么你总是可以反序列化 ResponseJsonNode 的实例并将其添加到数组或列表中。当然,该数组或列表将总是里面只有一个元素。所以你为什么需要这个仍然没有意义。但没有什么能真正阻止你。您只是希望 JSON 序列化程序以某种方式知道您想要这个,当然它不需要。您将改为编写代码来执行此操作。
  • 所以基本上没有库可以将 json 字符串转换为单独的对象,我必须为所有这些创建一个字符串解析器? Json 示例响应由数千个节点组成,它不仅仅是我示例中所示的一条记录 - 它以“,”结尾,表示有多个节点。

标签: c# json .net-core .net-6.0


【解决方案1】:

您显示的 JSON 不是数组。这就是为什么您不能将其反序列化为数组的原因。你能够将其反序列化为一个对象:

ResponseJsonNode jsonNode = JsonSerializer.Deserialize<ResponseJsonNode>(json);

然后,如果您希望该对象成为列表的一部分,您可以将其添加到列表中。例如:

List<ResponseJsonNode> jsonNodeList = new List<ResponseJsonNode>();
jsonNodeList.Add(jsonNode);

基本上,您遇到的问题是了解对象和对象数组之间的区别。你拥有的是一个对象。如果你想要一个数组,创建一个数组并将对象添加到它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多