Bagaimana cara membuat serial jenis C # anonim ke string JSON?

162

Saya mencoba menggunakan kode berikut untuk membuat serialkan jenis anonim ke JSON:

var serializer = new DataContractJsonSerializer(thing.GetType());
var ms = new MemoryStream();
serializer.WriteObject(ms, thing);
var json = Encoding.Default.GetString(ms.ToArray()); 

Namun, saya mendapatkan pengecualian berikut saat ini dijalankan:

Ketik '<> f__AnonymousType1`3 [System.Int32, System.Int32, System.Object []]' tidak dapat diserialisasi. Pertimbangkan menandainya dengan atribut DataContractAttribute, dan menandai semua anggotanya yang ingin Anda serialkan dengan atribut DataMemberAttribute. Lihat dokumentasi Microsoft .NET Framework untuk jenis yang didukung lainnya.

Saya tidak bisa menerapkan atribut ke tipe anonim (sejauh yang saya tahu). Apakah ada cara lain untuk melakukan serialisasi ini atau saya kehilangan sesuatu?

JC Grubbs
sumber

Jawaban:

159

Coba JavaScriptSerializer bukan DataContractJsonSerializer

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);
Nick Berardi
sumber
17
Trackback, sepertinya sudah tidak digunakan lagi di SP1.
Biswanath
7
untuk sesuatu yang sangat usang, tampaknya mulai digunakan di banyak kerangka kerja Microsoft baru, termasuk MVC. aspnet.codeplex.com/SourceControl/changeset/view/21528#266491
Nick Berardi
1
Bagaimana saya memasukkan proyek besarbesaran non -asp.net ini (aplikasi konsol)?
Alxandr
4
@Alxandr: Anda perlu referensi System.Web.Extensions.dlldan menambahkan using System.Web.Script.Serialization;pernyataan.
randomguy
1
Masalah @randomgui adalah jenis output proyek disetel ke profil klien.
Alxandr
75

Seperti yang disebutkan orang lain, Newtonsoft JSON.NET adalah pilihan yang baik. Berikut adalah contoh spesifik untuk serialisasi JSON sederhana:

return JsonConvert.SerializeObject(
    new
    {
       DataElement1,
       SomethingElse
    });

Saya telah menemukannya sebagai perpustakaan yang fleksibel dan fleksibel.

Matthew Nichols
sumber
14

Anda dapat mencoba ServiceStack JsonSerializer saya. Ini adalah serializer .NET JSON tercepat saat ini. Ini mendukung serialisasi DataContract's, Setiap Jenis POCO, Antarmuka, objek Terlambat termasuk jenis anonim, dll.

Contoh dasar

var customer = new Customer { Name="Joe Bloggs", Age=31 };
var json = customer.ToJson();
var fromJson = json.FromJson<Customer>(); 

Catatan: Hanya gunakan Microsoft JavaScriptSerializer jika kinerjanya tidak penting bagi Anda karena saya harus meninggalkannya dari tolok ukur saya karena itu hingga 40x-100x lebih lambat daripada serialisator JSON lainnya.

mitos
sumber
7
Saya menggunakan MS JavaScriptSerializer pada tumpukan MVC3 untuk membuat serialisasi objek dengan sejumlah kecil data. Cukup cepat dalam kasus ini, mengambil kurang dari satu milidetik untuk melakukan apa yang saya butuhkan. Permintaan DB itu sendiri membutuhkan waktu 50x-100x lebih lama, jadi itu bukan hambatan yang berarti dalam situasi saya.
Brian
2
Optimalisasi prematur adalah ... Ya, Anda tahu.
Mathias Lykkegaard Lorenzen
1
Tautan "tercepat .NET JSON serializer" adalah versi 404! Plus, jawaban ini lebih dari 5 1/2 tahun. Apakah Anda memiliki pembaruan tentang kinerja berbagai serializers .NET JSON?
ErikE
11

Harap perhatikan ini dari 2008. Hari ini saya berpendapat bahwa serializer harus dibuat di dalam dan bahwa Anda mungkin dapat menggunakan atribut swagger + untuk memberi tahu konsumen tentang titik akhir Anda dan mengembalikan data.


Saya akan berpendapat bahwa Anda seharusnya tidak membuat serial jenis anonim . Saya tahu godaan di sini; Anda ingin dengan cepat menghasilkan beberapa tipe yang dibuang yang hanya akan digunakan dalam lingkungan tipe yang longgar alias Javascript di browser. Namun, saya akan membuat tipe aktual dan menghiasnya sebagai Serializable. Maka Anda bisa sangat mengetik metode web Anda. Meskipun ini tidak masalah satu sedikit pun untuk Javascript, itu menambahkan beberapa dokumentasi diri ke metode. Setiap programmer yang cukup berpengalaman akan dapat melihat fungsi tanda tangan dan berkata, "Oh, ini tipe Foo! Saya tahu bagaimana seharusnya terlihat di JSON."

Karena itu, Anda dapat mencoba JSON.Net untuk melakukan serialisasi. Saya tidak tahu apakah itu akan berhasil

Jason Jackson
sumber
3
JSON.Net berfungsi dengan baik. Saya berpendapat bahwa Anda tidak boleh :), saya pikir itu cukup sah dalam banyak kasus.
aprilchild
2
Setelah melihat "membuang" jenis yang digunakan dalam MVC saya dapat melihat beberapa penggunaan yang menarik. Saya pikir ini adalah alat yang sangat berguna untuk ada di kotak alat .Net Anda.
Matthew Whited
12
Ini adalah poin yang saya juga telah melunak, terutama dalam hal tipe konsumsi saja. Tetapi jika objek melakukan perjalanan kembali ke server, atau digunakan di lebih dari satu lokasi, saya masih percaya bahwa membuat tipe akan menghasilkan lebih sedikit masalah.
Jason Jackson
De-serialisasi gaya DataContract tidak menangani jenis polimorfik dengan baik. Anda harus menulis de-serializer sendiri. Terlalu banyak pemeliharaan kode.
micahhoover
Kasus penggunaan di mana serialisasi jenis anonim berguna adalah pengujian unit untuk API web.
Howcheng
9

Cara tercepat yang saya temukan adalah ini:

var obj = new {Id = thing.Id, Name = thing.Name, Age = 30};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(obj);

Namespace: System.Web.Script.Serialization.JavaScriptSerializer

i31nGo
sumber
2
Dan untuk deserialisasi:. . dynamic myObject = JsonConvert.DeserializeObject <dynamic> (output); . . referensi: Newtonsoft.json.dll
i31nGo
2

Anda bisa menggunakan Newtonsoft.Json.

var warningJSON = JsonConvert.SerializeObject(new {
                warningMessage = "You have been warned..."
            });
Ahmet Arslan
sumber
1

Dengan asumsi Anda menggunakan ini untuk layanan web, Anda bisa menerapkan atribut berikut ke kelas:

[System.Web.Script.Services.ScriptService]

Kemudian atribut berikut untuk setiap metode yang harus mengembalikan Json:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

Dan atur jenis pengembalian untuk metode menjadi "objek"

Paul
sumber
Untuk layanan web ASP standar [ScriptMethod (ResponseFormat = ResponseFormat.Json)] tidak diperlukan pada metode ini, [WebMethod] akan melakukannya. Anda juga tidak boleh mengatur jenis kembali ke objek, itu bisa dan harus sangat diketik dengan jenis non-kompleks (yaitu dapat serial).
row1
-1
public static class JsonSerializer
{
    public static string Serialize<T>(this T data)
    {
        try
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream();
            serializer.WriteObject(stream, data);
            string jsonData = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);
            stream.Close();
            return jsonData;
        }
        catch
        {
            return "";
        }
    }
    public static T Deserialize<T>(this string jsonData)
    {
        try
        {
            DataContractJsonSerializer slzr = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
            T data = (T)slzr.ReadObject(stream);
            stream.Close();
            return data;
        }
        catch
        {
            return default(T);
        }
    }
}
Harry
sumber
Ini tidak membuat serial jenis anonim sesuai pertanyaan
Mark Sowul