Преобразование сложного JSON в общий список с помощью Newtonsoft - PullRequest
0 голосов
/ 11 декабря 2018

Ниже приведен 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 \ "}) для правильной десериализации. \ r \ nЧтобы исправить эту ошибку, либо измените JSON на объект JSON (например, {\" name \ ": \" value \ "}), либо измените десериализованныйвведите массив или тип, который реализует интерфейс коллекции (например, ICollection, IList), например List, который можно десериализовать из массива JSON.

Ответы [ 3 ]

0 голосов
/ 11 декабря 2018

Как сказал Натан Верри, у вас есть объект, наслоенный на другой объект, и из-за этого вы не можете десериализовать данные так, как вы этого хотите.Тем не менее, вы можете обойти это, если сначала создадите массив этих результатов, а затем присвойте его свойству 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()), но это гарантирует, что объект действительно имеет данные, а не просто ссылку на перечисление.

0 голосов
/ 12 декабря 2018

Большое спасибо Макс, Натан и другие.Итак, наконец, я сделал некоторые изменения в коде, и ниже приведен код, который я изменил, чтобы все заработало:

 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);
            }


        }

Надеюсь, это поможет и другим.

0 голосов
/ 11 декабря 2018

Проблема в том, что у вас есть промежуточный объект между вашей 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); 
...