[C#] Json.net으로 JSON 객체 배열 역 직렬화

반환 된 json에 대해 다음 예제 구조를 사용하는 API를 사용하려고합니다.

[
   {
      "customer":{
         "first_name":"Test",
         "last_name":"Account",
         "email":"test1@example.com",
         "organization":"",
         "reference":null,
         "id":3545134,
         "created_at":"2013-08-06T15:51:15-04:00",
         "updated_at":"2013-08-06T15:51:15-04:00",
         "address":"",
         "address_2":"",
         "city":"",
         "state":"",
         "zip":"",
         "country":"",
         "phone":""
      }
   },
   {
      "customer":{
         "first_name":"Test",
         "last_name":"Account2",
         "email":"test2@example.com",
         "organization":"",
         "reference":null,
         "id":3570462,
         "created_at":"2013-08-12T11:54:58-04:00",
         "updated_at":"2013-08-12T11:54:58-04:00",
         "address":"",
         "address_2":"",
         "city":"",
         "state":"",
         "zip":"",
         "country":"",
         "phone":""
      }
   }
]

JSON.net은 다음 구조와 같이 잘 작동합니다.

{
    "customer": {
        ["field1" : "value", etc...],
        ["field1" : "value", etc...],
    }
}

그러나 제공된 구조에 만족하도록하는 방법을 알 수 없습니다.

기본 JsonConvert.DeserializeObject (content)를 사용하면 고객 수가 정확하지만 모든 데이터가 null입니다.

CustomerList (아래)를 수행하면 “현재 JSON 배열을 역 직렬화 할 수 없음”예외가 발생합니다.

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

생각?



답변

Json을 역 직렬화하는 새 모델을 만들 수 있습니다 CustomerJson.

public class CustomerJson
{
    [JsonProperty("customer")]
    public Customer Customer { get; set; }
}

public class Customer
{
    [JsonProperty("first_name")]
    public string Firstname { get; set; }

    [JsonProperty("last_name")]
    public string Lastname { get; set; }

    ...
}

그리고 json을 쉽게 역 직렬화 할 수 있습니다.

JsonConvert.DeserializeObject<List<CustomerJson>>(json);

도움이 되길 바랍니다!

문서 : JSON 직렬화 및 역 직렬화


답변

모델을 생성하지 않으려는 경우 다음 코드를 사용하십시오.

var result = JsonConvert.DeserializeObject<
  List<Dictionary<string,
    Dictionary<string, string>>>>(content);

참고 :이 작동하지 않습니다 당신의 JSON 문자열입니다. 이것은 모든 JSON 구조에 대한 일반적인 솔루션 이 아닙니다 .


답변

허용 된 답변을 사용하면을 사용하여 각 레코드에 액세스 Customers[i].customer해야 CustomerJson하며 약간 성가신 추가 클래스 가 필요합니다 . 그렇게하지 않으려면 다음을 사용할 수 있습니다.

public class CustomerList
{
    [JsonConverter(typeof(MyListConverter))]
    public List<Customer> customer { get; set; }
}

List<>배열이 아닌을 사용하고 있습니다. 이제 다음 클래스를 만듭니다.

class MyListConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader);
        var list = Activator.CreateInstance(objectType) as System.Collections.IList;
        var itemType = objectType.GenericTypeArguments[0];
        foreach (var child in token.Values())
        {
            var childToken = child.Children().First();
            var newObject = Activator.CreateInstance(itemType);
            serializer.Populate(childToken.CreateReader(), newObject);
            list.Add(newObject);
        }
        return list;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
    }
    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}


답변

위에서 언급 한 내용을 약간 수정했습니다. 내 Json 형식은

{
    mycollection:{[
           {
               property0:value,
               property1:value,
             },
             {
               property0:value,
               property1:value,
             }
           ]

         }
       }

AlexDev의 응답을 사용하여 각 어린이를 반복하여 독자를 생성했습니다.

 public partial class myModel
{
    public static List<myModel> FromJson(string json) => JsonConvert.DeserializeObject<myModelList>(json, Converter.Settings).model;
}

 public class myModelList {
    [JsonConverter(typeof(myModelConverter))]
    public List<myModel> model { get; set; }

}

class myModelConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader);
        var list = Activator.CreateInstance(objectType) as System.Collections.IList;
        var itemType = objectType.GenericTypeArguments[0];
        foreach (var child in token.Children())  //mod here
        {
            var newObject = Activator.CreateInstance(itemType);
            serializer.Populate(child.CreateReader(), newObject); //mod here
            list.Add(newObject);
        }
        return list;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
    }
    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();

}


답변

JC_VA에서 추가 수정, 그가 가진 것을 취하고 MyModelConverter를 …

public class MyModelConverter : JsonConverter
{
    //objectType is the type as specified for List<myModel> (i.e. myModel)
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader); //json from myModelList > model
        var list = Activator.CreateInstance(objectType) as System.Collections.IList; // new list to return
        var itemType = objectType.GenericTypeArguments[0]; // type of the list (myModel)
        if (token.Type.ToString() == "Object") //Object
        {
            var child = token.Children();
            var newObject = Activator.CreateInstance(itemType);
            serializer.Populate(token.CreateReader(), newObject);
            list.Add(newObject);
        }
        else //Array
        {
            foreach (var child in token.Children())
            {
                var newObject = Activator.CreateInstance(itemType);
                serializer.Populate(child.CreateReader(), newObject);
                list.Add(newObject);
            }
        }
        return list;

    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
    }
    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}

이것은 다음 중 하나 인 json에서 작동합니다.

myModelList{
 model: [{ ... object ... }]
}

또는

myModelList{
 model: { ... object ... }
}

그들은 마치 마치 마치

myModelList{
 model: [{ ... object ... }]
}


답변