Десериализовать массив внутри объекта json с помощью JsonConvert.ДесериализиРовать объект()

#c# #xml-parsing #xml-serialization #json-deserialization #jsonserializer

#c# #синтаксический анализ xml #json.net #xml-сериализация #json-десериализация

Вопрос:

У меня есть требование, при котором у меня должен быть входящий объект json следующего формата:

 {
   "CustomerList": {
       "Customer": [{
            "CustomerCode" : "C123",
            "CustomerName" : "Peter"
       },
       {
            "CustomerCode" : "C456",
            "CustomerName" : "John"
       }]
   }
}
  

И у меня есть мой объект C # следующего формата:

 [System.Xml.Serialization.XmlArrayItemAttribute(IsNullable = "false")]
public Customer[] CustomerList
{
   get; set;
}

[System.Xml.Serialization.XmlTypeAttribute()]
public class Customer
{
    public string CustomerCode {get; set;}
    public string CustomerName {get; set;}
}
  

Во время десериализации с использованием JsonConvert.При десериализации объекта () я получаю следующую ошибку:
Не удается десериализовать текущий объект JSON в тип Customer[], поскольку для правильной десериализации этого типа требуется массив JSON (например, [1,2,3]).

С моей стороны ограничение заключается в том, что я не могу изменить входящий объект JSON, и я также не могу изменить структуру объекта C #. Итак, вопрос в том, есть ли способ напрямую сопоставить узел клиента во входящем Json с массивом CustomerList C #, без необходимости переименования или изменения структуры любого из них?

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

1. public Customer[] CustomerList это объявлено в каком-то классе! Можете ли вы поделиться кодом, который выполняет десериализацию?

2. да, список клиентов объявлен в классе. Я не использую никакой пользовательской десерлизации. Я просто использую JsonConvert. ДесериализиРовать объект() в Newtonsoft. Библиотека Json

3. Вам нужно предоставить общий доступ к коду, который выполняет десериализацию. Каким бы простым это ни было. Это поможет нам увидеть, есть ли проблема с кодом или нет, и может предложить соответствующее решение. На данный момент похоже, что вы десериализуете неправильный тип, но, не глядя на ваш код, это всего лишь предположение

4. я использую универсальную библиотеку, доступную здесь: newtonsoft.com/json , поэтому у него не должно возникнуть никаких проблем

Ответ №1:

На основе JSON, которым вы поделились, у вас должна быть следующая структура класса.

 public class Customer    {
    public string CustomerCode { get; set; } 
    public string CustomerName { get; set; } 
}

public class CustomerList    {
    public List<Customer> Customer { get; set; } 
}

public class RootObject  {
    public CustomerList CustomerList { get; set; } 
}
  

и затем вам нужно десериализовать JSON следующим образом.

 RootObject obj = JsonConvert.DeserializeObject<RootObject>(jsonString);
  

Здесь jsonString находится строковая переменная, которая содержит строку JSON.

Я надеюсь, что это поможет вам решить вашу проблему.

Ответ №2:

Для десериализации объекта JSON вам необходимо создать аналогичный класс C #.

 public class JsonObjectTest {
    [JsonPropertyName("CustomerList")]
    public Customer CustomerPreList {get;set;}
}

public class Customer {
    public List<CustomerObject> Customer {get;set;}
}

public class CustomerObject {

    public string CustomerCode { get; set; }
    public string CustomerName { get; set; }
}
  

После этого вы десериализуете объект JSON:

 CustomerList xmlData = JsonConvert.DeserializeObject<JsonObjectTest>(jsonObjectString).Select(data => 
    new CustomerList = data.CustomerPreList.toArray());
  

К сожалению, я не мог спросить вас, есть ли у вас разрешение на создание новых классов (мне нужно больше очков). Если это так, попробуйте AutoMapper создать политику сопоставления для этого конкретного случая.

Удачного кодирования 🙂

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

1. Нет ли способа отобразить, если класс C # имеет другую структуру. Например. с помощью [System.Xml.Serialization. XmlElementAttribute(«CustomerList.Customer»)][System.Xml.Сериализация. XmlArrayItemAttribute(IsNullable = «false»)] общедоступный клиент[] Список клиентов { получить; установить; }

Ответ №3:

Если вы не можете (или не хотите) добавлять новые классы, последние две строки GetCustomers() ниже должны делать то, что вы хотите. Просто присвоите его свойству CustomerList.

     public class Customer
    {
        public string? CustomerCode { get; set; }
        public string? CustomerName { get; set; }
    }


    public Customer[] GetCustomers()
    {
        string  json = @"{
                           'CustomerList':
                            {
                               'Customer': [{
                                    'CustomerCode' : 'C123',
                                    'CustomerName' : 'Peter'
                               },
                               {
                                    'CustomerCode' : 'C456',
                                    'CustomerName' : 'John'
                               }]
                           }
                        }";

        dynamic? contentObj = JsonConvert.DeserializeObject(json);
        return (contentObj?.CustomerList.Customer.ToObject<IList<Customer>>())?.ToArray() ?? new List<Customer>().ToArray();
    }
  

Я работаю с .NET 6.0, поэтому работаю со строкой? но для более ранних версий c # string должна делать то же самое. Поиграйте с обработкой null по мере необходимости.