Невозможно десериализовать массив JSON (например, [1,2,3]) в тип '', потому что для правильной десериализации типа требуется объект JSON (например, {«name»: «value»})

103

У меня такой JSON:

[
    {
        "Attributes": [
            {
                "Key": "Name",
                "Value": {
                    "Value": "Acc 1",
                    "Values": [
                        "Acc 1"
                    ]
                }
            },
            {
                "Key": "Id",
                "Value": {
                    "Value": "1",
                    "Values": [
                        "1"
                    ]
                }
            }
        ],
        "Name": "account",
        "Id": "1"
    },
    {
        "Attributes": [
            {
                "Key": "Name",
                "Value": {
                    "Value": "Acc 2",
                    "Values": [
                        "Acc 2"
                    ]
                }
            },
            {
                "Key": "Id",
                "Value": {
                    "Value": "2",
                    "Values": [
                        "2"
                    ]
                }
            }
        ],
        "Name": "account",
        "Id": "2"
    },
    {
        "Attributes": [
            {
                "Key": "Name",
                "Value": {
                    "Value": "Acc 3",
                    "Values": [
                        "Acc 3"
                    ]
                }
            },
            {
                "Key": "Id",
                "Value": {
                    "Value": "3",
                    "Values": [
                        "3"
                    ]
                }
            }
        ],
        "Name": "account",
        "Id": "2"
    }
]

А у меня есть такие классы:

public class RetrieveMultipleResponse
{
    public List<Attribute> Attributes { get; set; }
    public string Name { get; set; }
    public string Id { get; set; }
}

public class Value
{
    [JsonProperty("Value")]
    public string value { get; set; }
    public List<string> Values { get; set; }
}

public class Attribute
{
    public string Key { get; set; }
    public Value Value { get; set; }
}

Я пытаюсь десериализовать указанный выше JSON, используя приведенный ниже код:

var objResponse1 = JsonConvert.DeserializeObject<RetrieveMultipleResponse>(JsonStr);

но я получаю эту ошибку:

Невозможно десериализовать текущий массив JSON (например, [1,2,3]) в тип 'test.Model.RetrieveMultipleResponse', потому что типу требуется объект JSON (например, {"name": "value"}) для правильной десериализации. Чтобы исправить эту ошибку, либо измените JSON на объект JSON (например, {"name": "value"}), либо измените десериализованный тип на массив или тип, реализующий интерфейс коллекции (например, ICollection, IList), например List, который может быть десериализованным из массива JSON. JsonArrayAttribute также можно добавить к типу, чтобы заставить его десериализоваться из массива JSON. Путь '', строка 1, позиция 1.

Авинаш
источник

Ответы:

170

Ваша строка json заключена в квадратные скобки ( []), поэтому она интерпретируется как массив, а не как отдельный RetrieveMultipleResponseобъект. Следовательно, вам необходимо десериализовать его, чтобы набрать коллекцию RetrieveMultipleResponse, например:

var objResponse1 = 
    JsonConvert.DeserializeObject<List<RetrieveMultipleResponse>>(JsonStr);
har07
источник
Мне пришлось удалить «//» до «[», тогда у меня это сработало. спасибо
броский
1
Если вы хотите сохранить его как единый объект, а не коллекцию, можете ли вы просто выполнить JsonStr.Replace ("[", ""). Replace ("]", "") или это не будет хорошей практикой?
Rich
К вашему сведению, это не сработало для меня, потому что я получал свой JSON из API, и у меня целый день был неправильный URL-адрес. > <
w00ngy 05
1
Что здесь RetrieveMultipleResponse?
Причудливо
Спасибо, это сработало для меня var objResponse1 = JsonConvert.DeserializeObject <List <QuestionData>> (srt); // myWord = myQuestionData.Word; Debug.Log ("myWord" + objResponse1 [0] .Word);
StackBuddy 06
10

Если кто-то хочет поддерживать Generics (в методе расширения), это шаблон ...

public  static List<T> Deserialize<T>(this string SerializedJSONString)
{
    var stuff = JsonConvert.DeserializeObject<List<T>>(SerializedJSONString);
    return stuff;
}

Он используется так:

var rc = new MyHttpClient(URL);
//This response is the JSON Array (see posts above)
var response = rc.SendRequest();
var data = response.Deserialize<MyClassType>();

MyClassType выглядит так (должен соответствовать парам значений имени массива JSON)

[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
 public class MyClassType
 {
    [JsonProperty(PropertyName = "Id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "Name")]
    public string Name { get; set; }

    [JsonProperty(PropertyName = "Description")]
    public string Description { get; set; }

    [JsonProperty(PropertyName = "Manager")]
    public string Manager { get; set; }

    [JsonProperty(PropertyName = "LastUpdate")]
    public DateTime LastUpdate { get; set; }
 }

Используйте NUGET для загрузки Newtonsoft. Json добавьте ссылку там, где это необходимо ...

using Newtonsoft.Json;
Джон Питерс
источник
4

Не могу добавить комментарий к решению, но у меня это не сработало. Решение, которое сработало для меня, заключалось в использовании:

var des = (MyClass)Newtonsoft.Json.JsonConvert.DeserializeObject(response, typeof(MyClass)); 
return des.data.Count.ToString();

Десериализация массива JSON в строго типизированный объект .NET

TheNerdyNerd
источник
0
var objResponse1 = 
JsonConvert.DeserializeObject<List<RetrieveMultipleResponse>>(JsonStr);

работал!

майя
источник
Это не дает ответа на вопрос. Как только у вас будет достаточная репутация, вы сможете комментировать любой пост ; вместо этого предоставьте ответы, которые не требуют пояснений от спрашивающего . - Из отзыва
mike
0

Используйте это, FrontDataэто строка JSON:

var objResponse1 = JsonConvert.DeserializeObject<List<DataTransfer>>(FrontData);  

и извлечь список:

var a = objResponse1[0];
var b = a.CustomerData;
удорб б
источник