2012-02-26 26 views
9

Bir json verilerini bir model sınıfına serpiştirmeye çalışıyorum ancak başarısız oldum. İşte benim yaptığım:JSON dizisini türüne dönüştüremiyor - Json.NET

public CountryModel GetCountries() { 

     using (WebClient client = new WebClient()) { 

      var result = client.DownloadString("http://api.worldbank.org/incomeLevels/LIC/countries?format=json"); 

      var output = JsonConvert.DeserializeObject<List<CountryModel>>(result); 

      return output.First(); 
     } 
    } 

Bu gibi benim modeli görünür: http://api.worldbank.org/incomeLevels/LIC/countries?format=json

En fazla bu hata şudur: Burada alıyorum Json görebilirsiniz

public class CountryModel 
{ 
    public int Page { get; set; } 
    public int Pages { get; set; } 
    public int Per_Page { get; set; } 
    public int Total { get; set; } 

    public List<Country> Countries { get; set; } 
} 

public class Country 
{ 
    public int Id { get; set; } 
    public string Iso2Code { get; set; } 
    public string Name { get; set; } 
    public Region Region { get; set; } 
} 

public class Region 
{ 
    public int Id { get; set; } 
    public string Value { get; set; } 
} 

:

JSON dizisini 'Mvc4AsyncSample.Models.CountryModel' türüne dönüştürülemez. Hat 1, pozisyon 1.

+2

. Belki de XML formatını kullanırsanız daha iyi olur. – svick

+0

Evet, öyle düşünüyorum. Dizinin içine tek bir nesne koydular. Sanırım orada olmamalıydı. Gezmek için herhangi bir yol var mı? – tugberk

+0

XML çok daha temiz, bunun için giderdim: http://api.worldbank.org/incomeLevels/LIC/countries?format=xml –

cevap

17

Bir özel JsonConverter yazmak zorunda:

[JsonConverter(typeof(CountryModelConverter))] 
    public class CountryModel 
    { 
     public int Page { get; set; } 
     public int Pages { get; set; } 
     public int Per_Page { get; set; } 
     public int Total { get; set; } 

     public List<Country> Countries { get; set; } 
    } 

    public class Country 
    { 
     public string Id { get; set; } 
     public string Iso2Code { get; set; } 
     public string Name { get; set; } 
     public Region Region { get; set; } 
    } 

    public class Region 
    { 
     public string Id { get; set; } 
     public string Value { get; set; } 
    } 
:

public class CountryModelConverter : JsonConverter 
    { 

     public override bool CanConvert(Type objectType) 
     { 
      if (objectType == typeof(CountryModel)) 
      { 
       return true; 
      } 

      return false; 
     } 

     public override object ReadJson(JsonReader reader, Type objectType 
      , object existingValue, JsonSerializer serializer) 
     { 
      reader.Read(); //start array 
      //reader.Read(); //start object 
      JObject obj = (JObject)serializer.Deserialize(reader); 

      //{"page":1,"pages":1,"per_page":"50","total":35} 
      var model = new CountryModel(); 

      model.Page = Convert.ToInt32(((JValue)obj["page"]).Value); 
      model.Pages = Convert.ToInt32(((JValue)obj["pages"]).Value); 
      model.Per_Page = Int32.Parse((string) ((JValue)obj["per_page"]).Value); 
      model.Total = Convert.ToInt32(((JValue)obj["total"]).Value); 

      reader.Read(); //end object 

      model.Countries = serializer.Deserialize<List<Country>>(reader); 

      reader.Read(); //end array 

      return model; 
     } 

     public override void WriteJson(JsonWriter writer, object value 
      , JsonSerializer serializer) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

Ve bu dönüştürücü ile CountryModel etiketlemek (Ayrıca bazı intstring geçmek zorunda)

Öyleyse şu şekilde seri hale getirebilmeniz gerekir:

var output = JsonConvert.DeserializeObject<CountryModel>(result); 
+0

'CountryModel 'özelliklerinin seri hale getirilmesini' serializer.Deserialize (okuyucu) 'kullanarak basitleştiremez misiniz? – svick

+0

svick'in cevabı sadece okumanız gerektiğinde daha iyidir, "JsonConverter" sadece iki yoldan gitmeniz gerekiyorsa gerçekten gereklidir. –

+2

@svick Bunu düşündüm, sorun 'CountryModel' özniteliğine sahip, bu yüzden sonsuz döngüye giriyor, nesne modeli değiştiyse basitleştirilecek, ancak nesne modeline devam etmeye çalışıyordum. –

12

Bu, JSON'da XML'i temsil etme (çok iyi değil) girişimi gibi görünüyor.

[ 
    { 
    "page": 1, 
    … 
    }, 
    [ 
    { 
     "id": "AFG", 
     "name": "Afghanistan", 
     … 
    }, 
    { 
     "id": "BDI", 
     "name": "Burundi", 
     … 
    }, 
    … 
    ] 
] 

makul bir JSON (yani tesadüfen güzel modeliniz için eşleştirme) şu şekilde görünecektir iken:

Eğer JSON kullanmak istediğinizden emin değilseniz
{ 
    "page": 1, 
    …, 
    "countries": [ 
    { 
     "id": "AFG", 
     "name": "Afghanistan", 
     … 
    }, 
    { 
     "id": "BDI", 
     "name": "Burundi", 
     … 
    }, 
    … 
    ] 
} 

(ve JSON şuna benzer değil XML), önce Json.NET nesne modeli JSON serisi kaldırılırken bunu yapmak ve daha sonra model içine serisini:

var json = client.DownloadString("http://api.worldbank.org/incomeLevels/LIC/countries?format=json"); 

var array = (JArray)JsonConvert.DeserializeObject(json); 

var serializer = new JsonSerializer(); 

var countryModel = serializer.Deserialize<CountryModel>(array[0].CreateReader()); 

countryModel.Countries = serializer.Deserialize<List<Country>>(array[1].CreateReader()); 

return countryModel; 

için Id özelliklerini değiştirmek unutmayın string, çünkü oldukları gibi.

+0

Benim sürümümden çok daha kolay, güzel, okuyucuyu yerleşik nesnelerden oluşturabileceğinizi bilmiyordum. –

-1

Modeliniz JSON yapısıyla eşleşmiyor. Son 6 mülkünüzü kaçırıyor gibi görünüyor.

{ 
"id": "AFG", 
"iso2Code": "AF", 
"name": "Afghanistan", 
"region": { 
    "id": "SAS", 
    "value": "South Asia" 
}, 
"adminregion": { 
    "id": "SAS", 
    "value": "South Asia" 
}, 
"incomeLevel": { 
    "id": "LIC", 
    "value": "Low income" 
}, 
"lendingType": { 
    "id": "IDX", 
    "value": "IDA" 
}, 
"capitalCity": "Kabul", 
"longitude": "69.1761", 
"latitude": "34.5228" 

} iyi bir JSON gösterimi gibi görünmüyor

+7

Bu, seri hale getirme işlemini etkilemez. – tugberk

İlgili konular