繁体   English   中英

使用Newtonsoft将复杂的JSON转换为通用列表

[英]Convert complex JSON to Generic List using Newtonsoft

以下是一个Json:

[{
    "Result": {
        "description": "Application Security Supp Specialist",
        "code": "40000003"
    }
}, {
    "Result": {
        "description": "Gvt Cyber Intelligence Specialist",
        "code": "40001416"
    }
}, {
    "Result": {
        "description": "Gvt Record Retention Specialist",
        "code": "40001428"
    }
}]

下面是我创建的类结构,因为我需要将其填充到C#对象中。 我正在尝试创建RulesEngineOutput的集合,并用json内容填充它。

public class RulesEngineOutput
{
    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("code")]
    public string Code { get; set; }
}

public class RulesEngineOutputCollection
{
    public IEnumerable<RulesEngineOutput> ProbableRoles { get; set; }
}

我正在尝试使用以下代码实现这一目标:

var bodyJson = JsonConvert.SerializeObject(bodyString);
RulesEngineOutputCollection result = new RulesEngineOutputCollection();
foreach (var item in bodyJson)
{
    result = JsonConvert.DeserializeObject<RulesEngineOutputCollection>(item.ToString()); 
}

但这会在该项目获取一个字符时引发异常,我在想,我需要在循环中传递一个JSON对象,但我无法获取一个。 每次我得到的都是JSON字符串。

无法将当前JSON数组(例如[1,2,3])反序列化为类型'RulesEngineOutputCollection',因为该类型需要JSON对象(例如{\\“ name \\”:\\“ value \\”})才能正确反序列化。 \\ n要解决此错误,请将JSON更改为JSON对象(例如{\\“ name \\”:\\“ value \\”})或将反序列化类型更改为数组或实现集合接口的类型(例如ICollection,IList ),例如可以从JSON数组反序列化的List。

问题是您在RulesEngineOutput和集合之间有一个中间对象。 您需要这样重组对象:

public class RulesEngineOutput
{
    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("code")]
    public string Code { get; set; }
}

public class RulesEngineOutputResult
{
    public RulesEngineOutput Result { get; set; }
}

public class RulesEngineOutputCollection
{
    public IEnumerable<RulesEngineOutputResult> ProbableRoles { get; set; }
}

然后,当您完成此重组后,可以直接反序列化为RulesEngineOutputCollection而不是对象,然后再次进行迭代和反序列化。

result = JsonConvert.DeserializeObject<RulesEngineOutputCollection>(bodyString); 

非常感谢Max,Nathan和其他人。 所以最后我对代码进行了一些更改,下面是为了使事情正常进行而更改的代码:

 var jToken = JObject.Parse(responseContent);
        var bodyString = jToken.SelectToken("body");
        var bodyJson = JsonConvert.SerializeObject(bodyString);


        List<RulesEngineOutput> result = new List<RulesEngineOutput>();


        try
        {

            foreach (var item in bodyString)
            {
                var formattedItem = item.SelectToken("Result");
                var  resultItem = JsonConvert.DeserializeObject<RulesEngineOutput>(formattedItem.ToString());
                   result.Add(resultItem);
            }


        }

希望它也能帮助其他人。

正如Nathan Werry所说,您将一个对象分层到另一个对象中,因此,您无法以所需的方式反序列化数据。 但是,如果首先创建这些结果的数组,然后将其分配给ProbableRoles属性,则可以解决此问题:

var rules = new RulesEngineOutputCollection
{
    ProbableRoles = JsonConvert.DeserializeObject<Result[]>(bodyString).Select(r => r.Data).ToList()
};

public class Result
{
    [JsonProperty("Result")]
    public RulesEngineOutput Data { get; set; }
}

其他一切保持不变。 您基本上是从结果数组中创建一个新列表。 我还可以直接分配Select()结果(不调用.ToList() ),但这可以确保对象实际上具有数据,而不仅仅是引用枚举。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM