如何在不添加新 JObject 键/名称的情况下将 JArray 添加到 JObject 中?

Posted

技术标签:

【中文标题】如何在不添加新 JObject 键/名称的情况下将 JArray 添加到 JObject 中?【英文标题】:How would you add a JArray into a JObject without adding a new JObject key/name? 【发布时间】:2021-12-18 19:20:11 【问题描述】:

使用 .NET C#,我正在尝试从 JArray 创建一个新的 JObject。我有一个 FetchData JObject,我想返回一个数据 JObject 以进行数据驱动测试。这是我目前所拥有的:

public static JObject FetchData(string testMethodName)
        
            using (StreamReader r = new StreamReader("PathToJsonfile"))
            
                string jsonstring = r.ReadToEnd();
                JObject obj = JObject.Parse(jsonstring);
                JArray jsonArray = JArray.Parse(obj[testMethodName].ToString());

                JObject jObject = new JObject(new JProperty("test",jsonArray));

                return jObject;
            

        

我想返回一个与正在运行的 testMethod 相关的测试数据的 JObject。当我运行这段代码时,jObject 返回:

"test": [
    
      "loginId": "testuser1",
      "userCase": "verify for user"
    ,
    
      "loginId": "testuser2",
      "userCase": "verify for user"
    
  ]

我的问题是我只想在 JObject 中返回以下数组:

"loginId":"testuser1","userCase":"verify for user"

我研究了一段时间,如果不向新的 JObject 添加密钥,则无法找到解决方案,在这种情况下,密钥是“测试”。

这在 C# 中是否可行?

我也尝试将 JArray 直接添加到 JObject:

JObject jObject = new JObject(new JObject(jsonArray));

但出现错误:System.ArgumentException: '无法将 Newtonsoft.Json.Linq.JArray 添加到 Newtonsoft.json.Linq.JObject

我也尝试过像这样将数组添加到 JObject:

for (int i = 0; i < jsonArray.Count; i++)
                
                    jObject[i] = jsonArray[i];
                

但出现错误:System.ArgumentException:使用无效键值设置 JObject 值:0。应为对象属性名称。

fwiw 这就是我这样做的方式,它是 Java,它就像一个魅力,但我无法在 C# 中弄清楚。 Java 代码:

JSONObject[] jsonObject = new JSONObject[jsonArray.length()];
        for (int i = 0; i < jsonArray.length(); i++) 
            jsonObject[i] = jsonArray.getJSONObject(i);
        

【问题讨论】:

JArray.FromObject(myObject); "loginId":"testuser1","userCase":"verify for user" 不是数组而是对象。你能澄清一下你到底想返回什么 - json数组的第一个元素吗?还是将所有元素作为单独的JObjects?或者只是一个JArray 嗨@GuruStron,感谢您的回复。我想将所有元素的 JObject 作为单独的对象返回,如下所示: ["loginId":"testuser1","userCase":"verify for user","loginId":"testuser2","userCase":"验证用户"] 那不是json对象,是json数组,所以需要将返回类型改为JArray,返回jsonArray 你是对的@GuruStron。我意识到我现在没有问正确的问题。我想返回数组第一个元素的 JObject,像这样:"loginId":"testuser1","userCase":"verify for user",你知道我会怎么做吗? 【参考方案1】:

要获取数组的第一个元素,您可以执行以下操作:

var json = @"
""test"": [
    
      ""loginId"": ""testuser1"",
      ""userCase"": ""verify for user""
    ,
    
      ""loginId"": ""testuser2"",
      ""userCase"": ""verify for user""
    ]
";
var testMethodName = "test";
var jObject = JObject.Parse(json);
var first = (JObject)jObject[testMethodName][0]; // note that this can throw for multiple reasons

你的 java 代码的模拟是:

// parse jObject as earlier
var jArr = (JArray)jObject[testMethodName];
var jsonObjectArr = new JObject[jArr.Count];
for (int i = 0; i < jArr.Count; i++)

    jsonObjectArr[i] = (JObject)jArr[i];

或者你可以使用LINQ to JSON:

// parse jObject as earlier
var jsonObjectArr = jObject[testMethodName]
    .Children<JObject>()
    .ToArray();

【讨论】:

【参考方案2】:

为什么不像这样只返回数组的第一个对象:

public static JToken FetchOneDatum(string testMethodName)

  string jsonString = GetFileContent("sampleTest.txt");
  JObject obj = JObject.Parse(jsonString);
  JArray jsonArray = JArray.Parse(obj[testMethodName].ToString());
  return jsonArray[0];

您可以在此处找到整个 Visual Studio 解决方案: solution on GitHub

【讨论】:

【参考方案3】:

C# 方法 ;)

public class Test

    public string loginId  get; set; 
    public string userCase  get; set; 


public class Scenario

    public Test[] tests  get; set; 


// Usage
public static Test FetchData(string testMethodName)

    using (var reader = new StreamReader("PathToJsonfile"))
    
        var json = reader.ReadToEnd();
        var scenario = JsonConvert.DeserializeObject<Scenario>(json);

        return scenario.tests.First();
    

【讨论】:

以上是关于如何在不添加新 JObject 键/名称的情况下将 JArray 添加到 JObject 中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不从当前活动选项卡中获取焦点的情况下将子窗口添加到 QMdiArea(设置为 TAB 模式)?

如何在不从 DataFrame 转换并访问它的情况下将列添加到 Dataset?

MS Access Form:在没有键的情况下将新信息输入到两个链接表中

如何在不使用库的情况下将默认名称“选择文件”更改为“选择文档”? [复制]

如何在不跟踪索引的情况下将元素附加到列表?

如何在不使用 InterfaceBuilder 的情况下将 UISwitch(切换开关)添加到 UIToolBar