Saya relatif baru bekerja dengan data C # dan JSON dan saya mencari panduan. Saya menggunakan C # 3.0, dengan .NET3.5SP1, dan JSON.NET 3.5r6.
Saya memiliki kelas C # yang saya butuhkan untuk mengisi dari struktur JSON. Namun, tidak setiap struktur JSON untuk entri yang diambil dari layanan web berisi semua atribut yang mungkin ditentukan dalam kelas C #.
Saya telah melakukan apa yang tampaknya menjadi cara yang salah, sulit dan hanya memilih setiap nilai satu per satu dari JObject dan mengubah string menjadi properti kelas yang diinginkan.
JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);
MyAccount.EmployeeID = (string)o["employeeid"][0];
Apa cara terbaik untuk deserialize struktur JSON ke dalam kelas C # dan menangani kemungkinan data yang hilang dari sumber JSON?
Kelas saya didefinisikan sebagai:
public class MyAccount
{
[JsonProperty(PropertyName = "username")]
public string UserID { get; set; }
[JsonProperty(PropertyName = "givenname")]
public string GivenName { get; set; }
[JsonProperty(PropertyName = "sn")]
public string Surname { get; set; }
[JsonProperty(PropertyName = "passwordexpired")]
public DateTime PasswordExpire { get; set; }
[JsonProperty(PropertyName = "primaryaffiliation")]
public string PrimaryAffiliation { get; set; }
[JsonProperty(PropertyName = "affiliation")]
public string[] Affiliation { get; set; }
[JsonProperty(PropertyName = "affiliationstatus")]
public string AffiliationStatus { get; set; }
[JsonProperty(PropertyName = "affiliationmodifytimestamp")]
public DateTime AffiliationLastModified { get; set; }
[JsonProperty(PropertyName = "employeeid")]
public string EmployeeID { get; set; }
[JsonProperty(PropertyName = "accountstatus")]
public string AccountStatus { get; set; }
[JsonProperty(PropertyName = "accountstatusexpiration")]
public DateTime AccountStatusExpiration { get; set; }
[JsonProperty(PropertyName = "accountstatusexpmaxdate")]
public DateTime AccountStatusExpirationMaxDate { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
public DateTime AccountStatusModified { get; set; }
[JsonProperty(PropertyName = "accountstatusexpnotice")]
public string AccountStatusExpNotice { get; set; }
[JsonProperty(PropertyName = "accountstatusmodifiedby")]
public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }
[JsonProperty(PropertyName = "entrycreatedate")]
public DateTime EntryCreatedate { get; set; }
[JsonProperty(PropertyName = "entrydeactivationdate")]
public DateTime EntryDeactivationDate { get; set; }
}
Dan contoh JSON untuk diurai adalah:
{
"givenname": [
"Robert"
],
"passwordexpired": "20091031041550Z",
"accountstatus": [
"active"
],
"accountstatusexpiration": [
"20100612000000Z"
],
"accountstatusexpmaxdate": [
"20110410000000Z"
],
"accountstatusmodifiedby": {
"20100214173242Z": "tdecker",
"20100304003242Z": "jsmith",
"20100324103242Z": "jsmith",
"20100325000005Z": "rjones",
"20100326210634Z": "jsmith",
"20100326211130Z": "jsmith"
},
"accountstatusmodifytimestamp": [
"20100312001213Z"
],
"affiliation": [
"Employee",
"Contractor",
"Staff"
],
"affiliationmodifytimestamp": [
"20100312001213Z"
],
"affiliationstatus": [
"detached"
],
"entrycreatedate": [
"20000922072747Z"
],
"username": [
"rjohnson"
],
"primaryaffiliation": [
"Staff"
],
"employeeid": [
"999777666"
],
"sn": [
"Johnson"
]
}
sumber
Sudahkah Anda mencoba menggunakan metode DeserializeObject generik?
Setiap bidang yang hilang dalam data JSON harus dibiarkan NULL.
MEMPERBARUI:
Jika string JSON adalah array, coba ini:
jarray
harus menjadiList<MyAccount>
.PEMBARUAN LAIN:
Pengecualian yang Anda dapatkan tidak konsisten dengan array objek - Saya pikir serializer mengalami masalah dengan
accountstatusmodifiedby
properti yang diketikkan dengan Kamus Anda .Cobalah mengecualikan
accountstatusmodifiedby
properti dari serialisasi dan lihat apakah itu membantu. Jika ya, Anda mungkin perlu mewakili properti itu secara berbeda.Dokumentasi: Melakukan Serialisasi dan Deserialisasi JSON dengan Json.NET
sumber
DateTime AccountStatusExpiration
(misalnya) tidak dapat dibatalkan sebagaimana didefinisikan dalam kode. Apa yang diperlukan untuk membuatnya nullable? Cukup ubahDateTime
menjadiDateTime?
?Anda dapat menggunakan tipe C #
dynamic
untuk mempermudah. Teknik ini juga membuat re-factoring lebih sederhana karena tidak bergantung pada string-sihir.Json
The
json
String di bawah ini adalah respon sederhana dari panggilan http api dan mendefinisikan dua sifat:Id
danName
.C #
Gunakan
JsonConvert.DeserializeObject<dynamic>()
untuk menghilangkan tanda dari string ini menjadi tipe dinamis lalu cukup mengakses propertinya dengan cara yang biasa.Catatan : Tautan NuGet untuk perakitan NewtonSoft adalah http://nuget.org/packages/newtonsoft.json . Jangan lupa menambahkan:
using Newtonsoft.Json;
untuk mengakses kelas-kelas itu.sumber
DeserializeObject<dynamic>
adalah dengan definisi tidak "ketik-diperiksa". Jadi baris berikutresults.Id
danresults.Name
tidak dapat diverifikasi pada waktu kompilasi. Setiap kesalahan akan terjadi pada saat run-time. Bandingkan ini dengan panggilan yang sangat diketik sepertiDeserializeObject<List<MyAccount>>
. Referensi ke properti tersebut dapat dikonfirmasi pada waktu kompilasi. Penggunaandynamic
, meskipun mungkin nyaman, memperkenalkan "string ajaib" sebagai nama properti; pengurangan IMHO ketahanan.Kamu bisa memakai:
di sini:
json
adalah string json,obj
adalah objek target. Lihat: contohCatatan:
PopulateObject()
tidak akan menghapus data daftar obj, setelah ituPopulate()
,obj's
anggota daftar akan berisi data asli dan data dari string jsonsumber
Membangun dari jawaban bbant, ini adalah solusi lengkap saya untuk deserializing JSON dari URL jarak jauh.
Penggunaan akan seperti:
Di mana
FeedResult
kelas yang dihasilkan menggunakan Xamasoft JSON Class GeneratorBerikut adalah screenshot dari pengaturan yang saya gunakan, memungkinkan untuk nama properti aneh yang versi web tidak dapat menjelaskannya.
sumber
Saya menemukan saya saya telah membangun objek saya salah. Saya menggunakan http://json2csharp.com/ untuk menghasilkan kelas objek saya dari JSON. Setelah saya memiliki Oject yang benar, saya dapat melakukan tanpa masalah. Norbit, kesalahan Noob. Kupikir saya akan menambahkannya jika Anda memiliki masalah yang sama.
sumber
Anda dapat mencoba memeriksa beberapa generator kelas online untuk informasi lebih lanjut. Namun, saya yakin beberapa jawaban bermanfaat. Inilah pendekatan saya yang mungkin berguna.
Kode berikut dibuat dengan metode dinamis dalam pikiran.
Kode ini pada dasarnya memungkinkan Anda untuk mengakses anggota yang terkandung dalam string Json. Cara yang berbeda tanpa perlu kelas.
query
,trend
danurl
benda-benda yang terkandung dalam string Json.Anda juga dapat menggunakan situs web ini . Jangan mempercayai kelas 100%, tetapi Anda mendapatkan idenya.
sumber
Dengan asumsi data sampel Anda benar, nama Anda, dan entri lain yang dibungkus dengan tanda kurung adalah array di JS ... Anda akan ingin menggunakan Daftar untuk tipe data tersebut. dan Daftar untuk mengatakan akunstatusexpmaxtanggal ... Saya pikir Anda contoh memiliki tanggal yang salah diformat, jadi tidak pasti apa yang salah dalam contoh Anda.
Ini adalah pos lama, tetapi ingin mencatat masalah tersebut.
sumber