Bir C # anonim türünü bir JSON dizesine nasıl serileştiririm?


162

JSON için anonim bir tür serileştirmek için aşağıdaki kodu kullanmaya çalışıyorum:

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

Ancak, bu yürütüldüğünde aşağıdaki özel durumu alıyorum:

'<> F__AnonymousType1`3 [System.Int32, System.Int32, System.Object []]' serileştirilemez. DataContractAttribute özniteliğiyle işaretlemeyi ve DataMemberAttribute özniteliğiyle serileştirilmesini istediğiniz tüm üyelerini işaretlemeyi düşünün. Desteklenen diğer türler için Microsoft .NET Framework belgelerine bakın.

Anonim bir türe öznitelik uygulayamıyorum (bildiğim kadarıyla). Bu serileştirmeyi yapmanın başka bir yolu var mı yoksa bir şey mi kaçırıyorum?

Yanıtlar:


159

DataContractJsonSerializer yerine JavaScriptSerializer'ı deneyin

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);

17
Geri izleme, SP1'de kullanımdan kaldırılmış gibi görünüyor.
Biswanath

7
bu kadar eskimiş bir şey için, MVC de dahil olmak üzere birçok yeni Microsoft çerçevesinde kullanılıyor gibi görünüyor. aspnet.codeplex.com/SourceControl/changeset/view/21528#266491
Nick Berardi

1
Bu ia non-asp.net projesini (konsol uygulaması) nasıl ekleyebilirim?
Alxandr

4
@Alxandr: Başvuru yapmanız System.Web.Extensions.dllve bir using System.Web.Script.Serialization;ifade eklemeniz gerekir .
randomguy

1
@randomgui problemi proje çıktı türünün istemci profiline ayarlanmasıydı.
Alxandr

75

Diğerlerinin de belirttiği gibi, Newtonsoft JSON.NET iyi bir seçenektir. Basit JSON serileştirmesi için özel bir örnek:

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

Çok esnek ve çok yönlü bir kütüphane olduğunu gördüm.


14

Sen benim ServiceStack deneyebilirsiniz JsonSerializer öyle hızlı .NET JSON seri hale anda. DataContract'ın, Herhangi POCO Türünün, Arayüzlerin, anonim türler dahil geç bağlı nesnelerin serileştirilmesini destekler.

Temel Örnek

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

Not: Microsofts JavaScriptSerializer'ı yalnızca performans sizin için önemli değilse kullanın, çünkü diğer JSON serileştiricilerinden 40x-100x'e kadar daha yavaş olduğu için testlerimin dışında bırakmak zorunda kaldım .


7
Küçük miktarlarda veri ile nesneleri serileştirmek için MVC3 yığını MS JavaScriptSerializer kullanıyorum. Bu durumlarda oldukça hızlı, ihtiyacım olanı yapmak için bir milisaniyeden daha az zaman alıyor. DB sorgusunun kendisi 50x-100x daha uzun sürer, bu yüzden durumumda gerçekten önemli bir darboğaz değil.
Brian

2
Erken optimizasyon ... Biliyorsun.
Mathias Lykkegaard Lorenzen

1
"en hızlı .NET JSON serializer" bağlantı 404ing olduğunu! Ayrıca, bu cevap 5 1/2 yaşın üzerindedir. Çeşitli .NET JSON serileştiricilerinin performansıyla ilgili bir güncellemeniz var mı?
ErikE

11

Lütfen bunun 2008'den geldiğine dikkat edin. Bugün, serileştiricinin yerleşik olması gerektiğini ve tüketicileri uç noktanız ve dönüş verileriniz hakkında bilgilendirmek için muhtemelen swagger + özelliklerini kullanabileceğinizi iddia ediyorum.


Anonim bir türü serileştirmemeniz gerektiğini iddia ederim . Buradaki cazibeyi biliyorum; tarayıcıda gevşek bir ortamda, yani Javascript'te kullanılacak olan bazı atma türlerini hızlı bir şekilde oluşturmak istiyorsunuz. Yine de, gerçek bir tür oluşturup Serializable olarak dekore ederdim. Sonra web yöntemlerinizi güçlü bir şekilde yazabilirsiniz. Bu Javascript için bir iota önemli olmasa da, yönteme bazı kişisel belgeler ekler. Herhangi bir makul deneyimli programcı fonksiyon imzasına bakabilecek ve "Ah, bu Foo tipi! Bunun JSON'da nasıl görünmesi gerektiğini biliyorum."

Bunu söyledikten sonra, serileştirmeyi yapmak için JSON.Net'i deneyebilirsiniz . İşe yarayıp yaramayacağı hakkında hiçbir fikrim yok


3
JSON.Net gayet iyi çalışıyor. Yapmamalısın :), çoğu durumda oldukça meşru olduğunu düşünüyorum.
Nisan

2
MVC'de kullanılan "atmak" türlerini gördükten sonra bazı zorlayıcı kullanımlar görebiliyorum. Ben .Net araç kutunuzda olması çok kullanışlı bir araç olduğunu düşünüyorum.
Matthew

12
Bu, özellikle sadece tüketim türleri için de yumuşadığım bir noktadır. Ancak nesne sunucuya bir dönüş yolculuğu yapıyorsa veya birden fazla konumda kullanılıyorsa, yine de bir tür oluşturmanın daha az sorunla sonuçlanacağına inanıyorum.
Jason Jackson

DataContract stili serileştirme, polimorfik türleri iyi işlemez. Kendi de-serileştiricinizi yazmalısınız. Çok fazla kod bakımı.
micahhoover

Anonim türlerin serileştirilmesinin faydalı olduğu bir kullanım durumu, web API'leri için birim testlerdir.
howcheng

9

Bulduğum en hızlı yol şuydu:

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

Ad alanı: System.Web.Script.Serialization.JavaScriptSerializer


2
Ve serileştirme için. . dynamic myObject = JsonConvert.DeserializeObject <dinamik> (çıktı); . . başvuru: Newtonsoft.json.dll
i31nGo

2

Newtonsoft.Json kullanabilirsiniz.

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

1

Bunu bir web hizmeti için kullandığınızı varsayarsak, yalnızca aşağıdaki özniteliği sınıfa uygulayabilirsiniz:

[System.Web.Script.Services.ScriptService]

Sonra Json döndürmesi gereken her yönteme aşağıdaki öznitelik:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

Ve yöntemlerin dönüş türünü "nesne" olarak ayarlayın


Yöntemde standart bir ASP web hizmeti [ScriptMethod (ResponseFormat = ResponseFormat.Json)] gerekli değildir, [WebMethod] bunu yapar. Ayrıca, dönüş türünü nesneye ayarlamamalısınız, karmaşık olmayan (yani serileştirilebilir) türle güçlü bir şekilde yazılabilir ve yazılmalıdır.
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);
        }
    }
}

Bu soru başına anonim türleri serileştirmez
Mark Sowul
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.