Как десериализовать из моего массива JSON в массив словарей, значениями которых являются мои «ресурсные» объекты в C # .NET, используя Newtonsoft?

#c# #json #serialization #json.net #json-deserialization

#c# #json #сериализацию #json.net #json-десериализацию

Вопрос:

Я получаю следующую ошибку при попытке десериализовать мой JSON в Dictionary<string, Resources>[] :

Необработанное исключение типа ‘Newtonsoft.Json.Исключение JsonSerializationException’ произошло в Newtonsoft.Json.dll

Дополнительная информация: невозможно десериализовать текущий объект JSON (например, {«name»:»value»}) в тип ‘System .Коллекции.Generic.Dictionary`2[System.String,MyProject.Resource][]’ потому что для правильной десериализации типа требуется массив JSON (например, [1,2,3] ) .

Чтобы исправить эту ошибку, либо измените JSON на массив JSON (например, [1,2,3] ), либо измените десериализованный тип, чтобы он был нормальным.Тип NET (например, не примитивный тип, такой как integer, а не тип коллекции, такой как array или List), который может быть десериализован из объекта JSON. Атрибут JsonObjectAttribute также можно добавить к типу, чтобы заставить его десериализоваться из объекта JSON.

My Program.Main():

     public class Program
            {
                public static void Main(string[] Args)
                {
                    var options = new Options()
                    {
                        Option1 = "foo",
                        Option2 = "bar",
                        Resources = JsonConvert.DeserializeObject<Dictionary<string, Resource>[]>(resources.json)
                    };
                }
            }
  

My resources.json:

 {
    "global": [

        {
            "title": "global1",
            "url": "~/global1"
        },
        {
            "title": "global2",
            "url": "~/global2"
        }
    ],
    "ACC": [
        {
            "title": "acc1",
            "url": "~/acc1/"
        },
        {
            "title": "acc2",
            "url": "~/acc2/"
        }
    ],
    "ECC": [
        {
            "title": "ecc1",
            "url": "~/ecc1/"
        },
        {
            "title": "ecc2",
            "url": "~/ecc2/"
        }
    ],
    "ECB": [
        {
            "title": "ecb1",
            "url": "~/ecb1"
        }
    ]

}
  

Мой класс ресурсов:

 public class Resource
    {
        public List<string> titles { get; set; }

        public List<string> urls { get; set; }
    }
  

Мой класс Options:

 public class Options
    {
        public string Option1 { get; set; }
        public string Option2 { get; set; }
        public Dictionary<string, Resource>[] Resources { get; set; }
    }
  

Ответ №1:

Ваш JSON не представляет массив словарей ( Dictionary<string, Resource>[] ), он представляет словарь массивов ( Dictionary<string, Resource[]> ). Вот почему вы получаете ошибку.

Кроме того, ваш класс ресурсов должен быть определен следующим образом, чтобы соответствовать JSON:

 public class Resource
{
    public string Title { get; set; }
    public string Url { get; set; }
}
  

Затем вы можете десериализовать следующим образом:

  Resources = JsonConvert.DeserializeObject<Dictionary<string, Resource[]>>(resources.json)
  

Смотрите Здесь fiddle: https://dotnetfiddle.net/8s2eQd

Ответ №2:

Ваш Json не соответствует вашей структуре классов.
Если вы хотите сохранить структуру своего класса, ваш json должен выглядеть следующим образом:

 {
   "global":{
      "titles":[
         "global1",
         "global2"
      ],
      "urls":[
         "~/global1",
         "~/global2"
      ]
   },
   "acc":{
      "titles":[
         "acc1",
         "acc2"
      ],
      "urls":[
         "~/acc1",
         "~/acc2"
      ]
   },

   ...    

}
  

Если вы не можете повлиять на свой файл json (по какой-либо причине), ваша структура классов должна выглядеть следующим образом:

 public class Rootobject
{
   public Global[] global { get; set; }
   public ACC[] ACC { get; set; }
   public ECC[] ECC { get; set; }
   public ECB[] ECB { get; set; }
}

public class Global
{
   public string title { get; set; }
   public string url { get; set; }
}

public class ACC
{
   public string title { get; set; }
   public string url { get; set; }
}

public class ECC
{
   public string title { get; set; }
   public string url { get; set; }
}

public class ECB
{
   public string title { get; set; }
   public string url { get; set; }
}
  

Затем вы можете десериализовать его следующим образом:

 Resources = JsonConvert.DeserializeObject<Rootobject>(resources.json)
  

Небольшое замечание для следующего раза:
Если вы не уверены, как должна выглядеть структура вашего класса (относительно строки json), вы можете скопировать строку json и перейти к:

Visual Studio -> Редактировать -> Вставить специальный -> Вставить JSON как классы

и Visual Studio создаст соответствующую структуру классов.