Deserialize JSON menjadi objek dinamis C #?

965

Apakah ada cara untuk menghapus konten JSON menjadi tipe dinamis C # 4? Akan menyenangkan untuk melewatkan membuat banyak kelas untuk menggunakan DataContractJsonSerializer.

jswanson
sumber
5
Jika Anda menginginkan sesuatu yang 'dinamis', mengapa tidak hanya menggunakan accessor style get yang datang dengan sebagian besar decoder JSON yang tidak pergi ke objek biasa-lama? (misalnya apakah benar-benar diperlukan untuk pembuatan objek 'dinamis'?) json.org memiliki banyak tautan untuk implementasi C # JSON.
Saya sedang mengerjakan proyek yang mencoba untuk menjaga agar ketergantungan eksternal tetap minimum. Jadi, jika mungkin untuk sesuatu dengan stok .net serializers dan jenis yang akan disukai. Tentu saja jika itu tidak mungkin, saya akan memukul json.org. Terima kasih!
jswanson
42
Saya benar-benar terkejut tim C # menambahkan 'dinamis' tetapi kemudian tidak ada cara di CLR untuk mengubah objek JSON menjadi instance kelas CLR dinamis.
Frank Schwieterman
2
Sayangnya jawaban yang diterima tidak berfungsi di .NET 4 RTM. Saya memposting jawaban yang membantu saya menyelesaikan hal ini yang mungkin bermanfaat bagi orang lain.
Drew Noakes
(Walaupun tampaknya Newtonsoft JSON.NET cukup dekat. Namun, tidak ada contoh yang benar-benar bagus.)
Hot Licks

Jawaban:

659

Jika Anda senang memiliki ketergantungan pada System.Web.Helpersmajelis, maka Anda dapat menggunakan Jsonkelas:

dynamic data = Json.Decode(json);

Ini disertakan dengan kerangka kerja MVC sebagai unduhan tambahan untuk kerangka .NET 4. Pastikan memberi Vlad upvote jika itu membantu! Namun jika Anda tidak dapat menganggap lingkungan klien menyertakan DLL ini, maka baca terus.


Pendekatan deserialisasi alternatif disarankan di sini . Saya memodifikasi kode sedikit untuk memperbaiki bug dan sesuai dengan gaya pengkodean saya. Yang Anda butuhkan hanyalah kode ini dan referensi System.Web.Extensionsdari proyek Anda:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;

public sealed class DynamicJsonConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        return type == typeof(object) ? new DynamicJsonObject(dictionary) : null;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
    }

    #region Nested type: DynamicJsonObject

    private sealed class DynamicJsonObject : DynamicObject
    {
        private readonly IDictionary<string, object> _dictionary;

        public DynamicJsonObject(IDictionary<string, object> dictionary)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");
            _dictionary = dictionary;
        }

        public override string ToString()
        {
            var sb = new StringBuilder("{");
            ToString(sb);
            return sb.ToString();
        }

        private void ToString(StringBuilder sb)
        {
            var firstInDictionary = true;
            foreach (var pair in _dictionary)
            {
                if (!firstInDictionary)
                    sb.Append(",");
                firstInDictionary = false;
                var value = pair.Value;
                var name = pair.Key;
                if (value is string)
                {
                    sb.AppendFormat("{0}:\"{1}\"", name, value);
                }
                else if (value is IDictionary<string, object>)
                {
                    new DynamicJsonObject((IDictionary<string, object>)value).ToString(sb);
                }
                else if (value is ArrayList)
                {
                    sb.Append(name + ":[");
                    var firstInArray = true;
                    foreach (var arrayValue in (ArrayList)value)
                    {
                        if (!firstInArray)
                            sb.Append(",");
                        firstInArray = false;
                        if (arrayValue is IDictionary<string, object>)
                            new DynamicJsonObject((IDictionary<string, object>)arrayValue).ToString(sb);
                        else if (arrayValue is string)
                            sb.AppendFormat("\"{0}\"", arrayValue);
                        else
                            sb.AppendFormat("{0}", arrayValue);

                    }
                    sb.Append("]");
                }
                else
                {
                    sb.AppendFormat("{0}:{1}", name, value);
                }
            }
            sb.Append("}");
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (!_dictionary.TryGetValue(binder.Name, out result))
            {
                // return null to avoid exception.  caller can check for null this way...
                result = null;
                return true;
            }

            result = WrapResultObject(result);
            return true;
        }

        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            if (indexes.Length == 1 && indexes[0] != null)
            {
                if (!_dictionary.TryGetValue(indexes[0].ToString(), out result))
                {
                    // return null to avoid exception.  caller can check for null this way...
                    result = null;
                    return true;
                }

                result = WrapResultObject(result);
                return true;
            }

            return base.TryGetIndex(binder, indexes, out result);
        }

        private static object WrapResultObject(object result)
        {
            var dictionary = result as IDictionary<string, object>;
            if (dictionary != null)
                return new DynamicJsonObject(dictionary);

            var arrayList = result as ArrayList;
            if (arrayList != null && arrayList.Count > 0)
            {
                return arrayList[0] is IDictionary<string, object> 
                    ? new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x))) 
                    : new List<object>(arrayList.Cast<object>());
            }

            return result;
        }
    }

    #endregion
}

Anda bisa menggunakannya seperti ini:

string json = ...;

var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });

dynamic obj = serializer.Deserialize(json, typeof(object));

Jadi, diberi string JSON:

{
  "Items":[
    { "Name":"Apple", "Price":12.3 },
    { "Name":"Grape", "Price":3.21 }
  ],
  "Date":"21/11/2010"
}

Kode berikut akan berfungsi saat runtime:

dynamic data = serializer.Deserialize(json, typeof(object));

data.Date; // "21/11/2010"
data.Items.Count; // 2
data.Items[0].Name; // "Apple"
data.Items[0].Price; // 12.3 (as a decimal)
data.Items[1].Name; // "Grape"
data.Items[1].Price; // 3.21 (as a decimal)
Drew Noakes
sumber
1
Saya mendapatkan kesalahan dalam dynamic obj = serializer.Deserialize (json, typeof (objek)); mengatakan bahwa tidak ada kelebihan untuk metode dengan 2 argumen .. dll salah atau apa?
Stewie Griffin
32
Anda dapat menggunakan System.Web.Helpers.Json - ia menawarkan metode Decode yang mengembalikan objek dinamis. Saya juga memposting info ini sebagai jawaban.
Vlad Iliescu
2
Ini banyak membantu saya juga, tapi saya ingin tahu apa yang harus saya lakukan jika saya perlu menggunakan metode .Serialize, yang saat ini hanya melempar NotImplementedException ... Saya tidak terlalu akrab dengan kelas tertutup dan / atau abstrak yang diperluas kelas. Adakah yang bisa mengarahkan saya ke arah yang benar?
Cory W.
2
terkadang di js Anda memiliki bidang dengan karakter khusus seperti "warna latar belakang". Untuk mengakses bidang-bidang seperti itu di js, Anda melakukan obj ["background-color"]. Bagaimana saya bisa mengakses bidang tersebut dari c # setelah deserializing ke objek dinamis? Saya tidak bisa melakukan obj.background-color, tentu saja, dan obj ["background-color"] sepertinya tidak berfungsi. Akan lebih baik jika objek dinamis juga dapat diakses sebagai kamus, pada saat yang sama, persis seperti di js.
Radu Simionescu
2
@RaduSimionescu Saya mungkin agak terlambat, tapi mungkin ini membantu pengunjung masa depan. Saya memiliki masalah yang sama, hanya dengan nama-bidang params(yang merupakan kata kunci dalam C #). Selain TryGetMemberAnda dapat menimpa TryGetIndex, yang memberi Anda perilaku yang sama persis seperti di JS. Maka Anda bisa melakukan obj["params"]atau obj["background-color"]untuk nama bidang canggung.
Martin Ender
606

Ini cukup sederhana menggunakan Json.NET :

dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

Juga using Newtonsoft.Json.Linq:

dynamic stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

Dokumentasi: Meminta JSON dengan dinamis

Tom Peplow
sumber
9
@HotLicks: Untuk mengintrospeksi dinamika stufflakukan sesuatu seperti:foreach (Newtonsoft.Json.Linq.JProperty jproperty in stuff) { Console.WriteLine("jproperty.Name = {0}", jproperty.Name);}
Matthias
11
Apa perbedaan antara JsonConvert.DeserializeObject dan JObject.Parse? Jawabannya adalah menggunakan keduanya dengan cara yang sama untuk melakukan hal yang sama tetapi tidak menjelaskan perbedaannya.
cja
7
@ TomPeplow Mencoba ini. Itu tidak berhasil untuk saya. Dikatakan bahwa "JObject tidak mengimplementasikan 'Nama'".
Lee Louviere
4
@ cja tidak ada perbedaan: stackoverflow.com/questions/23645034/...
nawfal
8
Saya tidak bisa melakukan ini. Saya telah mempersempit masalah menjadi berada di dalam suatu asyncmetode. Jika saya membuat metode ini sinkron berfungsi seperti yang diharapkan. Namun, buat metode asyncdan saya tidak bisa mendapatkan dynamic, saya hanya mendapatkan object. Casting eksplisit tidak melakukan apa-apa, masih saja memberi saya object. Apakah ada orang lain yang mengalami ini?
codeConcussion
295

Anda dapat melakukan ini menggunakan System.Web.Helpers.Json - metode Decode-nya mengembalikan objek dinamis yang dapat Anda lintasi semau Anda.

Ini termasuk dalam perakitan System.Web.Helpers (.NET 4.0).

var dynamicObject = Json.Decode(jsonString);
Vlad Iliescu
sumber
25
FYI System.Web.Helpers.dll membutuhkan .net 4.0 tetapi tidak termasuk dalam .net 4.0. Ini dapat diinstal dengan ASP.NET MVC 3
jbtule
7
Anda akan menemukan majelis ini di grup Extensions di bawah Assemblies in Visual Studio 2012
W3Max
1
Adakah masalah dengan menggunakan dinamis? Bagaimana kami dapat menangani pengecualian secara efisien jika input JSON tidak mengandung properti ..
Usama Khalil
5
Jika Anda ingin sangat mengetik model maka pastikan untuk menggunakan metode Json.Decode <T> (string).
Mike
2
Untuk menambahkan perpustakaan ini ke proyek Anda: stackoverflow.com/questions/8037895/…
80

.NET 4.0 memiliki perpustakaan bawaan untuk melakukan ini:

using System.Web.Script.Serialization;
JavaScriptSerializer jss = new JavaScriptSerializer();
var d = jss.Deserialize<dynamic>(str);

Ini adalah cara paling sederhana.

Peter Long
sumber
27
Sudahkah Anda mencoba ini? Ia kembali Dictionary<string,object>. Kecuali jika saya melewatkan sesuatu, contoh Anda tidak mengembalikan objek dinamis.
sergiopereira
18
Ini tidak berfungsi, itu hanya mengembalikan dict dalam bentuk dinamis
mattmanser
55
@Peter Long Saya percaya saya telah gagal menyatakan kasus saya dengan jelas, teman baik. Biarkan saya mencoba memperbaiki kesalahan saya. Saya tahu apa itu dinamika. Ini tidak memungkinkan Anda untuk memasukkan objek JSON dan menggunakan d.code, Anda harus melakukan d ["code"]. Nilai, yang bukan yang diinginkan kebanyakan orang menemukan jawaban ini, kami sudah tahu cara mendapatkan kamus dan mengubahnya menjadi dinamis adalah membuang-buang waktu. Dengan hormat saya tidak setuju, tuan.
mattmanser
4
@mattmanser we already know how to get the dictionary and casting it to a dynamic,. Tidak harus berupa kamus. Json juga memiliki daftar selain kamus. Dan juga daftar dan kamus bisa disarangkan. Kode saya dapat menangani semua situasi ini. TAPI metode Anda TIDAK BISA.
Peter Long
4
@mattmanser benar; dimungkinkan untuk mengimplementasikan IDynamicMetaObjectProvider(atau menggunakan mis. ExpandoObject) yang mampu mencegat properti dan mencarinya di kamus internal. Ini dikombinasikan dengan penggunaan dynamickode memungkinkan seperti yang d.codeakan digunakan. Agak ada gunanya melemparkan kamus ke dinamis.
Stephen Drew
78

"Data JSON string" sederhana ke objek tanpa file DLL pihak ketiga:

WebClient client = new WebClient();
string getString = client.DownloadString("https://graph.facebook.com/zuck");

JavaScriptSerializer serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>(getString);
string name = item["name"];

//note: JavaScriptSerializer in this namespaces
//System.Web.Script.Serialization.JavaScriptSerializer

Catatan: Anda juga dapat menggunakan objek kustom Anda.

Personel item = serializer.Deserialize<Personel>(getString);
İbrahim Özbölük
sumber
4
Saya tidak mengerti. Ini adalah solusi yang paling sederhana dan tidak ada yang menyebutkannya.
cikatomo
2
ya itu sederhana :) kadang-kadang Anda perlu membuat serial tetapi tidak ingin menyertakan 3 bagian dll
İbrahim Özbölük
Dapatkah Anda menguraikan: bagaimana dinamis dapat mengakses objek deserialized melalui: myObject["myprop"]? Saya tahu ini dilakukan pada saat runtime tetapi bagaimana cara mengaksesnya melalui myObject["myprop"]valid?
Royi Namir
1
Anda dapat membatalkan deserialisasi objek Anda seperti Personel item = serializer.Deserialize <Personel> (getString); dan jika Anda menggunakan objek dinamis juga Anda dapat menggunakan array dan semuanya mungkin seperti objek setiap
İbrahim Özbölük
3
Untuk menggunakan namespace System.Web.Script.Serialization proyek Anda perlu referensi ke System.Web.Extensions.
StilgarISCA
28

JsonFx dapat menghapus konten JSON menjadi objek dinamis.

Serialize ke / dari tipe dinamis (default untuk .NET 4.0):

var reader = new JsonReader(); var writer = new JsonWriter();

string input = @"{ ""foo"": true, ""array"": [ 42, false, ""Hello!"", null ] }";
dynamic output = reader.Read(input);
Console.WriteLine(output.array[0]); // 42
string json = writer.Write(output);
Console.WriteLine(json); // {"foo":true,"array":[42,false,"Hello!",null]}
jbtule
sumber
19

Saya membuat versi baru dari DynamicJsonConverter yang menggunakan Objek Expando. Saya menggunakan objek expando, karena saya ingin serialisasi kembali dinamis ke JSON menggunakan Json.NET.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.Web.Script.Serialization;

public static class DynamicJson
{
    public static dynamic Parse(string json)
    {
        JavaScriptSerializer jss = new JavaScriptSerializer();
        jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });

        dynamic glossaryEntry = jss.Deserialize(json, typeof(object)) as dynamic;
        return glossaryEntry;
    }

    class DynamicJsonConverter : JavaScriptConverter
    {
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");

            var result = ToExpando(dictionary);

            return type == typeof(object) ? result : null;
        }

        private static ExpandoObject ToExpando(IDictionary<string, object> dictionary)
        {
            var result = new ExpandoObject();
            var dic = result as IDictionary<String, object>;

            foreach (var item in dictionary)
            {
                var valueAsDic = item.Value as IDictionary<string, object>;
                if (valueAsDic != null)
                {
                    dic.Add(item.Key, ToExpando(valueAsDic));
                    continue;
                }
                var arrayList = item.Value as ArrayList;
                if (arrayList != null && arrayList.Count > 0)
                {
                    dic.Add(item.Key, ToExpando(arrayList));
                    continue;
                }

                dic.Add(item.Key, item.Value);
            }
            return result;
        }

        private static ArrayList ToExpando(ArrayList obj)
        {
            ArrayList result = new ArrayList();

            foreach (var item in obj)
            {
                var valueAsDic = item as IDictionary<string, object>;
                if (valueAsDic != null)
                {
                    result.Add(ToExpando(valueAsDic));
                    continue;
                }

                var arrayList = item as ArrayList;
                if (arrayList != null && arrayList.Count > 0)
                {
                    result.Add(ToExpando(arrayList));
                    continue;
                }

                result.Add(item);
            }
            return result;
        }

        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override IEnumerable<Type> SupportedTypes
        {
            get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
        }
    }
}
Jason Bolton
sumber
18

Cara lain menggunakan Newtonsoft.Json :

dynamic stuff = Newtonsoft.Json.JsonConvert.DeserializeObject("{ color: 'red', value: 5 }");
string color = stuff.color;
int value = stuff.value;
Jonas Lundgren
sumber
14

Anda dapat mencapainya dengan bantuan Newtonsoft.Json. Instal Newtonsoft.Json dari Nuget dan:

using Newtonsoft.Json;

dynamic results = JsonConvert.DeserializeObject<dynamic>(YOUR_JSON);
Waleed Naveed
sumber
8

Cara paling sederhana adalah:

Cukup sertakan file DLL ini .

Gunakan kode seperti ini:

dynamic json = new JDynamic("{a:'abc'}");
// json.a is a string "abc"

dynamic json = new JDynamic("{a:3.1416}");
// json.a is 3.1416m

dynamic json = new JDynamic("{a:1}");
// json.a is

dynamic json = new JDynamic("[1,2,3]");
/json.Length/json.Count is 3
// And you can use json[0]/ json[2] to get the elements

dynamic json = new JDynamic("{a:[1,2,3]}");
//json.a.Length /json.a.Count is 3.
// And you can use  json.a[0]/ json.a[2] to get the elements

dynamic json = new JDynamic("[{b:1},{c:1}]");
// json.Length/json.Count is 2.
// And you can use the  json[0].b/json[1].c to get the num.
pengguna1006544
sumber
6

Anda dapat memperluas JavaScriptSerializer untuk menyalin secara kamus kamus yang dibuat untuk memperluas objek (s) dan kemudian menggunakannya secara dinamis:

static class JavaScriptSerializerExtensions
{
    public static dynamic DeserializeDynamic(this JavaScriptSerializer serializer, string value)
    {
        var dictionary = serializer.Deserialize<IDictionary<string, object>>(value);
        return GetExpando(dictionary);
    }

    private static ExpandoObject GetExpando(IDictionary<string, object> dictionary)
    {
        var expando = (IDictionary<string, object>)new ExpandoObject();

        foreach (var item in dictionary)
        {
            var innerDictionary = item.Value as IDictionary<string, object>;
            if (innerDictionary != null)
            {
                expando.Add(item.Key, GetExpando(innerDictionary));
            }
            else
            {
                expando.Add(item.Key, item.Value);
            }
        }

        return (ExpandoObject)expando;
    }
}

Maka Anda hanya perlu memiliki pernyataan menggunakan untuk namespace Anda mendefinisikan ekstensi di (pertimbangkan hanya mendefinisikan mereka di System.Web.Script.Serialization ... trik lain adalah tidak menggunakan namespace, maka Anda tidak perlu menggunakan pernyataan sama sekali) dan Anda dapat mengkonsumsinya seperti:

var serializer = new JavaScriptSerializer();
var value = serializer.DeserializeDynamic("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

var name = (string)value.Name; // Jon Smith
var age = (int)value.Age;      // 42

var address = value.Address;
var city = (string)address.City;   // New York
var state = (string)address.State; // NY
alonzofox
sumber
6

Kamu bisa menggunakan using Newtonsoft.Json

var jRoot = 
 JsonConvert.DeserializeObject<dynamic>(Encoding.UTF8.GetString(resolvedEvent.Event.Data));

resolvedEvent.Event.Data adalah tanggapan saya dari memanggil Acara inti.

Vivek Shukla
sumber
6

Saya menggunakan http://json2csharp.com/ untuk mendapatkan kelas yang mewakili objek JSON.

Memasukkan:

{
   "name":"John",
   "age":31,
   "city":"New York",
   "Childs":[
      {
         "name":"Jim",
         "age":11
      },
      {
         "name":"Tim",
         "age":9
      }
   ]
}

Keluaran:

public class Child
{
    public string name { get; set; }
    public int age { get; set; }
}

public class Person
{
    public string name { get; set; }
    public int age { get; set; }
    public string city { get; set; }
    public List<Child> Childs { get; set; }
}

Setelah itu saya menggunakan Newtonsoft.Json untuk mengisi kelas:

using Newtonsoft.Json;

namespace GitRepositoryCreator.Common
{
    class JObjects
    {
        public static string Get(object p_object)
        {
            return JsonConvert.SerializeObject(p_object);
        }
        internal static T Get<T>(string p_object)
        {
            return JsonConvert.DeserializeObject<T>(p_object);
        }
    }
}

Anda bisa menyebutnya seperti ini:

Person jsonClass = JObjects.Get<Person>(stringJson);

string stringJson = JObjects.Get(jsonClass);

PS:

Jika nama variabel JSON Anda bukan nama C # yang valid (nama dimulai dengan $) Anda dapat memperbaikinya seperti ini:

public class Exception
{
   [JsonProperty(PropertyName = "$id")]
   public string id { get; set; }
   public object innerException { get; set; }
   public string message { get; set; }
   public string typeName { get; set; }
   public string typeKey { get; set; }
   public int errorCode { get; set; }
   public int eventId { get; set; }
}
RoJaIt
sumber
5

Untuk itu saya akan menggunakan JSON.NET untuk melakukan parsing level rendah dari aliran JSON dan kemudian membangun hirarki objek dari instance ExpandoObjectkelas.

Daniel Earwicker
sumber
5

Saya menggunakan seperti ini dalam kode saya dan itu berfungsi dengan baik

using System.Web.Script.Serialization;
JavaScriptSerializer oJS = new JavaScriptSerializer();
RootObject oRootObject = new RootObject();
oRootObject = oJS.Deserialize<RootObject>(Your JSon String);
Vasim Shaikh
sumber
1
tapi bukan itu pertanyaannya. ada yang berbeda ketika Anda harus menentukan tipe untuk setiap string json dan bekerja dengan tipe dinamis.
Illuminati
5

Lihatlah artikel yang saya tulis di CodeProject, yang menjawab pertanyaan dengan tepat:

Jenis dinamis dengan JSON.NET

Ada terlalu banyak cara untuk memposting ulang semuanya di sini, dan bahkan kurang penting karena artikel itu memiliki lampiran dengan kunci / file sumber yang diperlukan.

vitaly-t
sumber
5

Pilihan lain adalah "Tempel JSON sebagai kelas" sehingga dapat di-deserialisasikan dengan cepat dan mudah.

  1. Cukup salin seluruh JSON Anda
  2. Di Visual Studio: Klik EditTempel SpesialTempel JSON sebagai kelas

Berikut adalah penjelasan yang lebih baik dan piccas ... 'Tempel JSON Sebagai Kelas' di ASP.NET dan Web Tools 2012.2 RC

nitsram
sumber
ini menyelamatkan saya banyak waktu! harus dipilih sebagai jawaban terbaik!
jsiot
4

Deserializing di JSON.NET bisa dinamis menggunakan JObjectkelas, yang termasuk dalam perpustakaan itu. String JSON saya mewakili kelas-kelas ini:

public class Foo {
   public int Age {get;set;}
   public Bar Bar {get;set;}
}

public class Bar {
   public DateTime BDay {get;set;}
}

Sekarang kita deserialize string TANPA mereferensikan kelas di atas:

var dyn = JsonConvert.DeserializeObject<JObject>(jsonAsFooString);

JProperty propAge = dyn.Properties().FirstOrDefault(i=>i.Name == "Age");
if(propAge != null) {
    int age = int.Parse(propAge.Value.ToString());
    Console.WriteLine("age=" + age);
}

//or as a one-liner:
int myage = int.Parse(dyn.Properties().First(i=>i.Name == "Age").Value.ToString());

Atau jika Anda ingin masuk lebih dalam:

var propBar = dyn.Properties().FirstOrDefault(i=>i.Name == "Bar");
if(propBar != null) {
    JObject o = (JObject)propBar.First();
    var propBDay = o.Properties().FirstOrDefault (i => i.Name=="BDay");
    if(propBDay != null) {
        DateTime bday = DateTime.Parse(propBDay.Value.ToString());
        Console.WriteLine("birthday=" + bday.ToString("MM/dd/yyyy"));
    }
}

//or as a one-liner:
DateTime mybday = DateTime.Parse(((JObject)dyn.Properties().First(i=>i.Name == "Bar").First()).Properties().First(i=>i.Name == "BDay").Value.ToString());

Lihat posting untuk contoh lengkap.

Chad Kuehn
sumber
Pendekatan ini memungkinkan untuk "melintasi" dokumen jSON, sehingga Anda dapat mengelola situasi di mana struktur JSON tidak diketahui atau variabel (misalnya, banyak API mengembalikan dokumen JSON yang sama sekali berbeda ketika terjadi kesalahan). Ada perpustakaan lain yang mengizinkan untuk melakukan itu, selain dari Newtonsoft.JSON (alias JSON.NET)?
Alex 75
4

Objek yang Anda inginkan DynamicJSONObject termasuk dalam System.Web.Helpers.dll dari paket Halaman Web ASP.NET, yang merupakan bagian dari WebMatrix.

Nick Daniels
sumber
4

Ada perpustakaan JSON ringan untuk C # disebut SimpleJson .

Ini mendukung. NET 3.5+, Silverlight dan Windows Phone 7.

Ini mendukung dinamis untuk .NET 4.0

Itu juga dapat diinstal sebagai paket NuGet

Install-Package SimpleJson
prabir
sumber
4

Gunakan DataSet (C #) dengan JavaScript. Fungsi sederhana untuk membuat aliran JSON dengan input DataSet. Buat konten JSON seperti (dataset multi-tabel):

[[{a:1,b:2,c:3},{a:3,b:5,c:6}],[{a:23,b:45,c:35},{a:58,b:59,c:45}]]

Hanya sisi klien, gunakan eval. Sebagai contoh,

var d = eval('[[{a:1,b:2,c:3},{a:3,b:5,c:6}],[{a:23,b:45,c:35},{a:58,b:59,c:45}]]')

Kemudian gunakan:

d[0][0].a // out 1 from table 0 row 0

d[1][1].b // out 59 from table 1 row 1

// Created by Behnam Mohammadi And Saeed Ahmadian
public string jsonMini(DataSet ds)
{
    int t = 0, r = 0, c = 0;
    string stream = "[";

    for (t = 0; t < ds.Tables.Count; t++)
    {
        stream += "[";
        for (r = 0; r < ds.Tables[t].Rows.Count; r++)
        {
            stream += "{";
            for (c = 0; c < ds.Tables[t].Columns.Count; c++)
            {
                stream += ds.Tables[t].Columns[c].ToString() + ":'" +
                          ds.Tables[t].Rows[r][c].ToString() + "',";
            }
            if (c>0)
                stream = stream.Substring(0, stream.Length - 1);
            stream += "},";
        }
        if (r>0)
            stream = stream.Substring(0, stream.Length - 1);
        stream += "],";
    }
    if (t>0)
        stream = stream.Substring(0, stream.Length - 1);
    stream += "];";
    return stream;
}
Behnam Mohammadi
sumber
3

Untuk mendapatkan ExpandoObject:

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

Container container = JsonConvert.Deserialize<Container>(jsonAsString, new ExpandoObjectConverter());
Ryan Norbauer
sumber
3

Coba ini:

  var units = new { Name = "Phone", Color= "White" };
    var jsonResponse = JsonConvert.DeserializeAnonymousType(json, units);
Nirupam
sumber
3

Cara mengurai konten JSON mudah dengan dynamic & JavaScriptSerializer

Silakan tambahkan referensi System.Web.Extensions dan tambahkan namespace ini using System.Web.Script.Serialization;di atas:

public static void EasyJson()
{
    var jsonText = @"{
        ""some_number"": 108.541,
        ""date_time"": ""2011-04-13T15:34:09Z"",
        ""serial_number"": ""SN1234""
    }";

    var jss = new JavaScriptSerializer();
    var dict = jss.Deserialize<dynamic>(jsonText);

    Console.WriteLine(dict["some_number"]);
    Console.ReadLine();
}

Cara mengurai json yang bersarang & kompleks dengan dinamis & JavaScriptSerializer

Silakan tambahkan referensi System.Web.Extensions dan tambahkan namespace ini using System.Web.Script.Serialization;di atas:

public static void ComplexJson()
{
    var jsonText = @"{
        ""some_number"": 108.541,
        ""date_time"": ""2011-04-13T15:34:09Z"",
        ""serial_number"": ""SN1234"",
        ""more_data"": {
            ""field1"": 1.0,
            ""field2"": ""hello""
        }
    }";

    var jss = new JavaScriptSerializer();
    var dict = jss.Deserialize<dynamic>(jsonText);

    Console.WriteLine(dict["some_number"]);
    Console.WriteLine(dict["more_data"]["field2"]);
    Console.ReadLine();
}
Kabut
sumber
1

Dengan Cinchoo ETL - pustaka sumber terbuka yang tersedia untuk mengurai JSON menjadi objek dinamis:

string json = @"{
    ""key1"": [
        {
            ""action"": ""open"",
            ""timestamp"": ""2018-09-05 20:46:00"",
            ""url"": null,
            ""ip"": ""66.102.6.98""
        }
    ]
}";
using (var p = ChoJSONReader.LoadText(json)
    .WithJSONPath("$.*")
    )
{
    foreach (var rec in p)
    {
        Console.WriteLine("Action: " + rec.action);
        Console.WriteLine("Timestamp: " + rec.timestamp);
        Console.WriteLine("URL: " + rec.url);
        Console.WriteLine("IP address: " + rec.ip);
    }
}

Keluaran:

Action: open
Timestamp: 2018-09-05 20:46:00
URL: http://www.google.com
IP address: 66.102.6.98

Penafian: Saya penulis perpustakaan ini.

RajN
sumber
0

coba cara ini!

Contoh JSON:

  [{
            "id": 140,
            "group": 1,
            "text": "xxx",
            "creation_date": 123456,
            "created_by": "[email protected]",
            "tags": ["xxxxx"]
        }, {
            "id": 141,
            "group": 1,
            "text": "xxxx",
            "creation_date": 123456,
            "created_by": "[email protected]",
            "tags": ["xxxxx"]
        }]

Kode C #:

        var jsonString = (File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(),"delete_result.json")));
        var objects = JsonConvert.DeserializeObject<dynamic>(jsonString);
        foreach(var o in objects)
        {
            Console.WriteLine($"{o.id.ToString()}");
        }
Baja biru
sumber