Deserialize JSON dengan C #

206

Saya mencoba untuk membatalkan deserialisasi panggilan Graph API teman Facebook ke daftar objek. Objek JSON terlihat seperti:

{"data":[{"id":"518523721","name":"ftyft"},
         {"id":"527032438","name":"ftyftyf"},
         {"id":"527572047","name":"ftgft"},
         {"id":"531141884","name":"ftftft"},
         {"id":"532652067","name"...

List<EFacebook> facebooks = new JavaScriptSerializer().Deserialize<List<EFacebook>>(result);

Ini tidak berfungsi, karena objek primitif tidak valid. Bagaimana saya bisa membatalkan deserialisasi ini?

Peter Mortensen
sumber
3
tulis deserializer khusus untuk memenuhi kebutuhan json tersebut ...
ashutosh raina
2
atau Anda dapat menggunakan Dictionary<string,string>, periksa: stackoverflow.com/questions/7699972/…
Kakashi
9
Teman Anda: json2csharp.com
nawfal
4
Sebenarnya studio visual (per 2013, atau 2012 dengan alat web diinstal) memiliki fungsi yang tepat ini dibangun di: Edit> Tempel Spesial> Tempel JSON Sebagai Kelas
floomby

Jawaban:

264

Anda perlu membuat struktur seperti ini:

public class Friends
{

    public List<FacebookFriend> data {get; set;}
}

public class FacebookFriend
{

    public string id {get; set;}
    public string name {get; set;}
}

Maka Anda harus dapat melakukan:

Friends facebookFriends = new JavaScriptSerializer().Deserialize<Friends>(result);

Nama-nama kelas saya hanyalah sebuah contoh. Anda harus menggunakan nama yang benar.

Menambahkan tes sampel:

string json =
    @"{""data"":[{""id"":""518523721"",""name"":""ftyft""}, {""id"":""527032438"",""name"":""ftyftyf""}, {""id"":""527572047"",""name"":""ftgft""}, {""id"":""531141884"",""name"":""ftftft""}]}";

Friends facebookFriends = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Friends>(json);

foreach(var item in facebookFriends.data)
{
    Console.WriteLine("id: {0}, name: {1}", item.id, item.name);
}

Menghasilkan:

id: 518523721, name: ftyft
id: 527032438, name: ftyftyf
id: 527572047, name: ftgft
id: 531141884, name: ftftft
Icarus
sumber
3
Ya, itu yang tidak ingin saya lakukan, buat objek baru untuk menggendong anak-anaknya. Saya pikir saya akan substring json mengambil benda primitif. Terima kasih.
@Kevin Holditch terima kasih atas koreksinya. Saya melewatkan satu bagian penting :)
Icarus
2
Apa yang saya tidak suka tentang System.Web.Script.Serialization.JavaScriptSerializer () ini adalah bahwa Anda selalu membutuhkan tipe T. yang didefinisikan. Di Jawa ada pustaka org.java ini (paket) yang tetap semua anonim: "JSONObject [" param "]. JSONarray (5)" dll
olahraga
2
Penting untuk dicatat bahwa setter untuk properti id dan nama harus dibiarkan publik. Jika mereka diatur ke pribadi atau dilindungi, deserialisasi akan dijalankan tanpa kesalahan tetapi semua data akan menjadi nol.
Isaac Zais
2
@sports, Anda dapat melakukannya di C # dengan deserializing ke dinamis, tetapi kinerja jauh lebih baik jika Anda deserialize ke tipe yang dikenal.
PRMan
50

Terkadang saya lebih suka objek dinamis:

public JsonResult GetJson()
{
  string res;
  WebClient client = new WebClient();

  // Download string
  string value = client.DownloadString("https://api.instagram.com/v1/users/000000000/media/recent/?client_id=clientId");

  // Write values
  res = value;
  dynamic dyn = JsonConvert.DeserializeObject(res);
  var lstInstagramObjects = new List<InstagramModel>();

  foreach(var obj in dyn.data)
  {
    lstInstagramObjects.Add(new InstagramModel()
    {
      Link = (obj.link != null) ? obj.link.ToString() : "",
      VideoUrl = (obj.videos != null) ? obj.videos.standard_resolution.url.ToString() : "",
      CommentsCount = int.Parse(obj.comments.count.ToString()),
      LikesCount = int.Parse(obj.likes.count.ToString()),
      CreatedTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds((double.Parse(obj.created_time.ToString()))),
      ImageUrl = (obj.images != null) ? obj.images.standard_resolution.url.ToString() : "",
      User = new InstagramModel.UserAccount()
             {
               username = obj.user.username,
               website = obj.user.website,
               profile_picture = obj.user.profile_picture,
               full_name = obj.user.full_name,
               bio = obj.user.bio,
               id = obj.user.id
             }
    });
  }

  return Json(lstInstagramObjects, JsonRequestBehavior.AllowGet);
}
Bishoy Hanna
sumber
Suatu contoh contoh di mana ini berguna adalah ketika objek yang saya coba deserialize menjadi berisi properti yang merupakan antarmuka
soupy1976
2
Penjelasan akan diurutkan.
Peter Mortensen
Mengapa Anda lebih suka ini daripada jawaban yang diterima oleh @Icarus?
Mempertanyakan
@Pertanyaan, deserialising ke kelas tipe kuat akan mengabaikan properti yang tidak ada di kelas Anda, sementara deserialising ke objek dinamis hanya akan mengembalikan dinamis. Objek net yang fleksibel untuk properti baru yang dibuat di masa depan tanpa persyaratan untuk memperbarui kelas Anda. (seperti yang saya katakan, terkadang tidak standar)
Bishoy Hanna
39

Cara terbaik untuk membuat kelas-kelas ini secara otomatis untuk Anda adalah dengan menyalin output JSON Anda dan melemparkannya ke sini:

http://json2csharp.com/

Ini akan memberi Anda titik awal untuk menyentuh kelas Anda untuk deserialisasi.

Jack Fairfield
sumber
28

Sangat mudah kita dapat mem-parsing konten JSON dengan bantuan kamus dan JavaScriptSerializer. Berikut adalah contoh kode yang digunakan untuk mengurai konten JSON dari file ashx.

var jss = new JavaScriptSerializer();
string json = new StreamReader(context.Request.InputStream).ReadToEnd();
Dictionary<string, string> sData = jss.Deserialize<Dictionary<string, string>>(json);
string _Name = sData["Name"].ToString();
string _Subject = sData["Subject"].ToString();
string _Email = sData["Email"].ToString();
string _Details = sData["Details"].ToString();
Thomas
sumber
3
Solusi ini sangat berguna jika Anda tidak punya waktu atau perlu membuat kontrak data. Terutama jika Anda tertarik hanya beberapa atribut yang terkubur dalam struktur JSON. Dalam situasi itu Anda dapat menggunakan serangkaian pernyataan untuk menavigasi ke apa yang Anda butuhkan. Catatan: tipe untuk deserialize mungkin juga salah satu dari yang berikut: Kamus <string, object> atau ArrayList (ketika sebuah node memiliki struktur berulang).
Philippe Monnet
1
Saya mendapatkan pengecualian waktu berjalan dengan ini: Tidak ada konstruktor tanpa parameter didefinisikan untuk jenis 'System.String' pada baris kode deserialize.
RSK
20

Newtonsoft.JSONadalah solusi yang bagus untuk situasi seperti ini. Juga Newtonsof.JSONlebih cepat dari yang lain, seperti JavaScriptSerializer,DataContractJsonSerializer .

Dalam sampel ini, Anda dapat mengikuti:

var jsonData = JObject.Parse("your JSON data here");

Kemudian Anda dapat menggunakan jsonData JArray, dan Anda dapat menggunakan afor loop untuk mendapatkan data di setiap iterasi.

Saya juga ingin menambahkan sesuatu:

for (int i = 0; (JArray)jsonData["data"].Count; i++)
{
    var data = jsonData[i - 1];
}

Bekerja dengan objek dinamis dan menggunakan serialize Newtonsoft adalah pilihan yang baik.

OnurBulbul
sumber
15

Saya setuju dengan Icarus (akan berkomentar jika saya bisa), tetapi alih-alih menggunakan kelas CustomObject , saya akan menggunakan Kamus (kalau-kalau Facebook menambahkan sesuatu).

private class MyFacebookClass
{
    public IList<IDictionary<string, string>> data { get; set; }
}

atau

private class MyFacebookClass
{
    public IList<IDictionary<string, object>> data { get; set; }
}
Stijn Bollen
sumber
3
Menggunakan dinamis berfungsi lebih baik di versi baru. public IList<IDictionary<string, dynmaic>> data { get; set; }
BJury
3

Serialisasi:

// Convert an object to JSON string format
string jsonData = JsonConvert.SerializeObject(obj);

Response.Write(jsonData);

Deserialisasi ::

Untuk menghilangkan bakteri objek dinamis

  string json = @"{
      'Name': 'name',
      'Description': 'des'
    }";

var res = JsonConvert.DeserializeObject< dynamic>(json);

Response.Write(res.Name);
ravula sandeep
sumber
3

Anda dapat menggunakan ekstensi ini

public static class JsonExtensions
{
   public static T ToObject<T>(this string jsonText)
   {
       return JsonConvert.DeserializeObject<T>(jsonText);
   }

   public static string ToJson<T>(this T obj)
   {
       return JsonConvert.SerializeObject(obj);
   }
}
Hidayet R. Colkusu
sumber
1

Berikut ini adalah situs lain yang akan membantu Anda dengan semua kode yang Anda butuhkan selama Anda memiliki string JSON yang diformat dengan benar:

https://app.quicktype.io/

Liknes
sumber
1

Jika Anda menggunakan .NET Core 3.0, Anda dapat menggunakan System.Text.Json (yang sekarang sudah ada di dalamnya) untuk membatalkan deserialisasi JSON.

Langkah pertama adalah membuat kelas untuk memodelkan JSON. Ada banyak alat yang dapat membantu dengan ini, dan beberapa jawaban di sini mencantumkannya.

Beberapa opsi adalah http://json2csharp.com , http://app.quicktype.io , atau menggunakan Visual Studio (menu EditTempel SpesialTempel JSON sebagai kelas ).

public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class Response
{
    public List<Person> Data { get; set; }
}

Kemudian Anda dapat deserialize menggunakan:

var people = JsonSerializer.Deserialize<Response>(json);

Jika Anda perlu menambahkan pengaturan, seperti camelCasepenanganan, kemudian meneruskan pengaturan serializer ke deserializer seperti ini:

var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var person = JsonSerializer.Deserialize<Response>(json, options);
haldo
sumber