Saya memiliki kelas yang berisi enum
properti, dan setelah serialisasi objek menggunakan JavaScriptSerializer
, hasil json saya berisi nilai integer enumerasi daripada string
"namanya". Apakah ada cara untuk mendapatkan enum sebagai string
di json saya tanpa harus membuat kebiasaan JavaScriptConverter
? Mungkin ada atribut yang saya dapat menghias enum
definisi, atau properti objek, dengan?
Sebagai contoh:
enum Gender { Male, Female }
class Person
{
int Age { get; set; }
Gender Gender { get; set; }
}
Hasil json yang diinginkan:
{ "Age": 35, "Gender": "Male" }
Idealnya mencari jawaban dengan built-in kelas .NET framework, jika tidak memungkinkan alternatif (seperti Json.net) dipersilakan.
Jawaban:
Tidak, tidak ada atribut khusus yang dapat Anda gunakan.
JavaScriptSerializer
cerita bersambungenums
ke nilai numerik mereka dan bukan representasi string mereka. Anda perlu menggunakan serialisasi khusus untuk membuat serialisasienum
sebagai namanya alih-alih nilai numerik.Jika Anda dapat menggunakan JSON.Net
JavaScriptSerializer
daripada melihat jawaban pada pertanyaan ini yang disediakan oleh OmerBakhari : JSON.net membahas use case ini (melalui atribut[JsonConverter(typeof(StringEnumConverter))]
) dan banyak lainnya yang tidak ditangani oleh serializers .net yang dibangun. Berikut ini tautan yang membandingkan fitur dan fungsi serialis .sumber
JsonConverter
tidak akan berfungsi.Saya telah menemukan bahwa Json.NET menyediakan fungsionalitas tepat yang saya cari dengan
StringEnumConverter
atribut:Lebih detail tersedia di
StringEnumConverter
dokumentasi .Ada tempat lain untuk mengkonfigurasi konverter ini secara lebih global:
enum sendiri jika Anda ingin enum selalu serial / deserialized sebagai string:
Jika ada yang ingin menghindari dekorasi atribut, Anda dapat menambahkan konverter ke JsonSerializer Anda (disarankan oleh Bjørn Egil ):
dan itu akan bekerja untuk setiap enum yang dilihatnya selama serialisasi itu (disarankan oleh Travis ).
atau JsonConverter (disarankan oleh pisang ):
Selain itu Anda dapat mengontrol casing dan apakah nomor masih diterima dengan menggunakan konstruktor StringEnumConverter (NamingStrategy, Boolean) .
sumber
Controller
atau secara manual menimpa setiap serialisasi.camelCase
output):new StringEnumConverter { CamelCaseText = true }
Tambahkan di bawah ini ke global.asax Anda untuk serialisasi JSON dari c # enum sebagai string
sumber
Formatting
keIndented
?@Iggy answer menetapkan serialisasi JSON dari c # enum sebagai string hanya untuk ASP.NET (API Web dan sebagainya).
Tetapi untuk membuatnya bekerja juga dengan serialisasi ad hoc, tambahkan berikut ke kelas awal Anda (seperti Global.asax Application_Start)
Informasi lebih lanjut tentang halaman Json.NET
Selain itu, untuk meminta anggota enum Anda membuat cerita bersambung / deserialize ke / dari teks tertentu, gunakan
atribut, seperti ini:
sumber
[EnumMember]
.CamelCaseText
properti sekarang ditandai usang. Cara baru untuk instantiate konverter:new StringEnumConverter(new CamelCaseNamingStrategy())
Saya tidak dapat mengubah model sumber seperti pada jawaban teratas (dari @ob.), Dan saya tidak ingin mendaftarkannya secara global seperti @Iggy. Jadi saya menggabungkan https://stackoverflow.com/a/2870420/237091 dan @ Iggy's https://stackoverflow.com/a/18152942/237091 untuk memungkinkan pengaturan konverter string pada saat perintah SerializeObject itu sendiri:
sumber
Kombinasi jawaban Omer Bokhari dan uri adalah selalu merupakan solusi saya karena nilai yang ingin saya berikan biasanya berbeda dari apa yang saya miliki di enum saya khususnya bahwa saya ingin dapat mengubah enum saya jika saya perlu.
Jadi, jika ada yang tertarik, ini adalah sesuatu seperti ini:
sumber
JsonPropertyAttribute
untuk anggota enum dan bekerja untuk tugas deserializtion sederhana. Sayangnya, selama tweak manual denganJToken
s itu diabaikan. HappillyEnumMemberAttribute
bekerja seperti pesona. Terima kasih!JavaScriptSerializer
?Hal ini mudah dilakukan dengan menambahkan
ScriptIgnore
atribut keGender
properti, menyebabkan ia tidak serial, dan menambahkanGenderString
properti yang tidak mendapatkan serial:sumber
Versi jawaban Stephen ini tidak mengubah nama di JSON:
sumber
DataContractJsonSerializer
tidakJavaScriptSerializer
Inilah jawaban untuk newtonsoft.json
sumber
true
ke jenis JsonConverter Anda seperti ini:[JsonConverter(typeof(StringEnumConverter), true)]
ASP.NET Core way:
https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e
sumber
Anda juga dapat menambahkan konverter ke Anda
JsonSerializer
jika Anda tidak ingin menggunakanJsonConverter
atribut:Ini akan bekerja untuk setiap
enum
yang dilihatnya selama serialisasi itu.sumber
Berikut ini adalah solusi sederhana yang membuat serial C-enum sisi-server untuk JSON dan menggunakan hasilnya untuk mengisi sisi klien
<select>
elemen . Ini berfungsi untuk enum sederhana dan enum bitflag.Saya telah memasukkan solusi ujung ke ujung karena saya pikir sebagian besar orang yang ingin membuat serial C # enum ke JSON mungkin juga akan menggunakannya untuk mengisi
<select>
drop-down.Ini dia:
Contoh Enum
Enum kompleks yang menggunakan OR bitwise untuk menghasilkan sistem izin. Jadi Anda tidak bisa mengandalkan indeks sederhana [0,1,2 ..] untuk nilai integer enum.
Sisi Server - C #
Kode di atas menggunakan kerangka kerja NancyFX untuk menangani permintaan Dapatkan. Ini menggunakan
Response.AsJson()
metode pembantu Nancy - tetapi jangan khawatir, Anda dapat menggunakan formatter JSON standar karena enum telah diproyeksikan menjadi jenis anonim sederhana yang siap untuk serialisasi.JSON yang dihasilkan
Sisi Klien - CoffeeScript
HTML Sebelumnya
HTML Setelah
sumber
Untuk inti ASP.Net Cukup tambahkan berikut ini ke Kelas Startup Anda:
sumber
Anda dapat membuat JsonSerializerSettings dengan panggilan ke JsonConverter.SerializeObject seperti di bawah ini:
sumber
Melihat bahwa tidak ada jawaban untuk serialisasi ketika ada atribut Deskripsi.
Ini implementasi saya yang mendukung atribut Deskripsi.
Enum:
Pemakaian:
sumber
Untuk .Net Core: -
sumber
Microsoft.AspNetCore.Mvc.Formatters.Json
paket NuGet, sepertinya itu hanya metode perpanjanganIMvcCoreBuilder
, bukanIMvcBuilder
. Jadi itu digunakan sepertiservices.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
.Di .net core 3 ini sekarang dimungkinkan dengan kelas bawaan di System.Text.Json:
Untuk mengonfigurasi
JsonStringEnumConverter
dengan dekorasi atribut untuk properti tertentu:Jika Anda ingin selalu mengonversi enum sebagai string, letakkan atribut di enum itu sendiri.
sumber
Asp.Net Core 3 dengan System.Text.Json
sumber
Kalau-kalau ada orang yang menemukan hal di atas tidak cukup, saya akhirnya puas dengan kelebihan ini:
sumber
Ini adalah pertanyaan lama tapi saya pikir saya akan berkontribusi untuk berjaga-jaga. Dalam proyek saya, saya menggunakan model terpisah untuk permintaan Json. Model biasanya memiliki nama yang sama dengan objek domain dengan awalan "Json". Model dipetakan menggunakan AutoMapper . Dengan meminta model json mendeklarasikan properti string yang merupakan enum pada kelas domain, AutoMapper akan memutuskan untuk presentasi stringnya.
Jika Anda bertanya-tanya, saya perlu model terpisah untuk kelas serial Json karena serializer inbuilt muncul dengan referensi melingkar sebaliknya.
Semoga ini bisa membantu seseorang.
sumber
Anda benar-benar dapat menggunakan JavaScriptConverter untuk mencapai ini dengan JavaScriptSerializer bawaan. Dengan mengonversi enum Anda menjadi Uri, Anda dapat menyandikannya sebagai string.
Saya telah menjelaskan bagaimana melakukan ini untuk kencan tetapi ini dapat digunakan untuk enum juga. Format JSON DateTime Kustom untuk .NET JavaScriptSerializer .
sumber
Tidak yakin apakah ini masih relevan tetapi saya harus menulis langsung ke file json dan saya datang dengan berikut ini beberapa jawaban stackoverflow bersama-sama
Ini memastikan semua kunci json saya huruf kecil mulai sesuai dengan "aturan" json. Memformatnya dengan lekukan dan mengabaikan nol dalam output. Sedap dengan menambahkan StringEnumConverter itu mencetak enum dengan nilai string mereka.
Secara pribadi saya menemukan ini paling bersih yang bisa saya buat, tanpa harus mengotori model dengan anotasi.
pemakaian:
sumber
Saya telah mengumpulkan semua bagian dari solusi ini menggunakan
Newtonsoft.Json
perpustakaan. Ini memperbaiki masalah enum dan juga membuat penanganan kesalahan jauh lebih baik, dan berfungsi di layanan yang di-host IIS. Ini kode yang cukup banyak, sehingga Anda dapat menemukannya di GitHub di sini: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.csAnda harus menambahkan beberapa entri ke
Web.config
agar dapat berfungsi, Anda dapat melihat contoh file di sini: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.configsumber
Dan untuk VB.net saya menemukan karya-karya berikut:
sumber
Opsi yang sedikit lebih tahan di masa depan
Menghadapi pertanyaan yang sama, kami memutuskan bahwa kami membutuhkan versi khusus
StringEnumConverter
untuk memastikan bahwa nilai enum kami dapat berkembang dari waktu ke waktu tanpa merusak secara serampangan pada sisi deserialisasi (lihat latar belakang di bawah). MenggunakanSafeEnumConverter
bawah ini memungkinkan deserialization untuk menyelesaikan bahkan jika payload mengandung nilai untuk enum yang tidak memiliki definisi bernama, lebih dekat dengan bagaimana konversi int-to-enum akan bekerja.Pemakaian:
atau
Sumber:
Latar Belakang
Ketika kami melihat menggunakan
StringEnumConverter
, masalah yang kami miliki adalah bahwa kami juga membutuhkan kepasifan untuk kasus ketika nilai enum baru ditambahkan, tetapi tidak setiap klien segera menyadari nilai baru. Dalam kasus ini,StringEnumConverter
paket dengan Newtonsoft JSON melemparJsonSerializationException
mirip dengan "Kesalahan mengkonversi nilai SomeString untuk mengetik EnumType" dan kemudian seluruh proses deserialisasi gagal. Ini adalah pemecah kesepakatan bagi kami, karena bahkan jika klien berencana mengabaikan / membuang nilai properti yang tidak dimengerti, ia masih harus mampu melakukan deserialisasi sisa muatan!sumber
sumber
sumber