Десериализовать массив строк в список C#

#c# #.net-core #restsharp

#c# #.net-core #restsharp

Вопрос:

У меня есть необработанные данные JSON, которые выглядят следующим образом:

 {
    "Pages": 0,
    "Page": null,
    "Rows": null,
    "OrderBy": null,
    "Desc": false,
    "TotalRows": 36,
    "HasError": false,
    "Error": null,
    "Result": {
        "fileTypes": [
            {
                "id": 22,
                "description": "Cleaning Procedures",
                "Codes": ""
            },
            {
                "id": 32,
                "description": "Data Drop",
                "Codes": "["DB","IE"]"
            },
            {
                "id": 4,
                "description": "Data Sheet",
                "Codes": ""
            },
            {
                "id": 30,
                "description": "Description of Operation",
                "Codes": ""
            },
            {
                "id": 11,
                "description": "Diagram",
                "Codes": ""
            },
            {
                "id": 2,
                "description": "Drawing",
                "Codes": "["DR"]"
            }
        ]
    }
}
  

И C # Model , который выглядит следующим образом:

 public class Filetype
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("description")]
    public string Description { get; set; }
    [JsonProperty("Codes")]
    //public string Codes { get; set; }

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

Однако Newtonsoft не десериализует коды в список кодов, а возвращает

["DB","IE"] в первом элементе списка , или , «» , ( null ).

Буду признателен за любую помощь в этом.

Комментарии:

1. Однако это неверное ожидание. "Codes": "anything here" это строка, а не набор строк. Итак, NewtonSoft работает так, как ожидалось. Ваш ввод довольно неоптимален.

2. Каждое значение for Codes заключено в кавычки, что делает его строкой, а не массивом. "Codes": "["DB","IE"]" должно быть "Codes": ["DB","IE"] .

3. О, в таком случае у вас есть строка JSON в БД. Вам нужно исправить на стороне сервера, а не на стороне клиента … потому что: если вы извлекаете это из БД в виде строки , устанавливаете поле модели в эту строку (т. Е. model.Codes = stringFromDB; ), А затем сериализуете в json, вы получите именно то, что видите здесь.

4. @LeszekP Это действительно не помогло бы здесь. Проблема может быть исправлена с обеих сторон, но не с помощью автоматической генерации кода.

5. Действительно, мой комментарий был слишком коротким. Это не исправило бы это, это был просто совет, как отладить его в следующий раз. Если я делаю исключение, чтобы получить список строк, но сгенерированный код — это просто строка, тогда что-то не так, и нужно исследовать в Json / XML и т. Д. Это был просто комментарий / подсказка, а не ответ, поскольку уже есть действительный ответ от @matmahnke. Приветствия

Ответ №1:

код имеет следующее значение «[«DB», «IE»]», но список в json не нуждается в кавычках

значение кодов в json должно быть таким

  "Codes": ["DB","IE"]
  

Комментарии:

1. @MichaelLeipper Хорошо, с этим покончено: Вы можете исправить это с обеих сторон. Какой из них вы бы предпочли? На сервере или клиенте?

Ответ №2:

На стороне клиента :

Если одно из свойств является строковой сериализацией Json.
Вы можете добавить свойство, [JsonIgnore] которое представляет результат десериализации :

 public class Foo{
    public string BarsInString {get;set;}       
    [JsonIgnore]
    public Bar[] Bars 
    {
        get 
         {
            return JsonConvert.DeserializeObject<Bar[]>(UserInput);
         }
       set 
        {
           BarsInString = JsonConvert.SerializeObject(value);
        }     
    }
}
  

Живая демонстрация: https://dotnetfiddle.net/l5JWVb

Я выбрал что-то большее, чем an List<string> для иллюстрации. В вашем случае это будет сводиться к:

 public class Filetype
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("description")]
    public string Description { get; set; }
    [JsonProperty("Codes")]
    public string CodesInJson { get; set; }

    [JsonIgnore]
    public List<string> Codes {
        get 
         {
            return JsonConvert.DeserializeObject<List<string>>(CodesInJson);
         }
       set 
        {
           CodesInJson = JsonConvert.SerializeObject(value);
        }     
    }
}
  

На стороне сервера:

Если одно из свойств является сериализацией Json чего-то другого, вы можете десериализовать его перед отправкой. Используя тот же код:

 JsonConvert.DeserializeObject<List<string>>(myJsonFromDb);
  

Комментарии:

1. Возможно, стоит добавить, что вы можете исправить это и на сервере , десериализовав строку json из базы данных в список<string> в модели, которая затем снова сериализуется в json. Некоторые драйверы db могут сделать это за вас, если вы сообщите им, какие столбцы на самом деле являются json. (Зависит от базы данных и драйвера)

2. Изо всех сил старался превратить это во что-то понятное. Я не добавлял часть о db-драйверах, потому что я просто не знал об этом. Вы можете отредактировать ответ, если хотите что-то добавить.