Apakah ada cara untuk menghapus konten JSON menjadi tipe dinamis C # 4? Akan menyenangkan untuk melewatkan membuat banyak kelas untuk menggunakan DataContractJsonSerializer
.
Apakah ada cara untuk menghapus konten JSON menjadi tipe dinamis C # 4? Akan menyenangkan untuk melewatkan membuat banyak kelas untuk menggunakan DataContractJsonSerializer
.
Jawaban:
Jika Anda senang memiliki ketergantungan pada System.Web.Helpers
majelis, maka Anda dapat menggunakan Json
kelas:
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.Extensions
dari 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)
params
(yang merupakan kata kunci dalam C #). Selain TryGetMember
Anda 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.
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
stuff
lakukan sesuatu seperti:foreach (Newtonsoft.Json.Linq.JProperty jproperty in stuff) { Console.WriteLine("jproperty.Name = {0}", jproperty.Name);}
async
metode. Jika saya membuat metode ini sinkron berfungsi seperti yang diharapkan. Namun, buat metode async
dan 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?
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);
.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.
Dictionary<string,object>
. Kecuali jika saya melewatkan sesuatu, contoh Anda tidak mengembalikan objek dinamis.
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.
IDynamicMetaObjectProvider
(atau menggunakan mis. ExpandoObject
) yang mampu mencegat properti dan mencarinya di kamus internal. Ini dikombinasikan dengan penggunaan dynamic
kode memungkinkan seperti yang d.code
akan digunakan. Agak ada gunanya melemparkan kamus ke dinamis.
"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);
myObject["myprop"]
? Saya tahu ini dilakukan pada saat runtime tetapi bagaimana cara mengaksesnya melalui myObject["myprop"]
valid?
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]}
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) })); }
}
}
}
Cara lain menggunakan Newtonsoft.Json :
dynamic stuff = Newtonsoft.Json.JsonConvert.DeserializeObject("{ color: 'red', value: 5 }");
string color = stuff.color;
int value = stuff.value;
Anda dapat mencapainya dengan bantuan Newtonsoft.Json. Instal Newtonsoft.Json dari Nuget dan:
using Newtonsoft.Json;
dynamic results = JsonConvert.DeserializeObject<dynamic>(YOUR_JSON);
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.
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
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.
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; }
}
Untuk itu saya akan menggunakan JSON.NET untuk melakukan parsing level rendah dari aliran JSON dan kemudian membangun hirarki objek dari instance ExpandoObject
kelas.
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);
Lihatlah artikel yang saya tulis di CodeProject, yang menjawab pertanyaan dengan tepat:
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.
Pilihan lain adalah "Tempel JSON sebagai kelas" sehingga dapat di-deserialisasikan dengan cepat dan mudah.
Berikut adalah penjelasan yang lebih baik dan piccas ... 'Tempel JSON Sebagai Kelas' di ASP.NET dan Web Tools 2012.2 RC
Deserializing di JSON.NET bisa dinamis menggunakan JObject
kelas, 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.
Objek yang Anda inginkan DynamicJSONObject termasuk dalam System.Web.Helpers.dll dari paket Halaman Web ASP.NET, yang merupakan bagian dari WebMatrix.
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
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;
}
Untuk mendapatkan ExpandoObject:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
Container container = JsonConvert.Deserialize<Container>(jsonAsString, new ExpandoObjectConverter());
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();
}
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();
}
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.
coba cara ini!
Contoh JSON:
[{
"id": 140,
"group": 1,
"text": "xxx",
"creation_date": 123456,
"created_by": "xxx@gmail.co",
"tags": ["xxxxx"]
}, {
"id": 141,
"group": 1,
"text": "xxxx",
"creation_date": 123456,
"created_by": "xxx@gmail.com",
"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()}");
}