ยกเลิกการทำให้เป็นแนว JSON เป็นวัตถุแบบไดนามิก C #?


965

มีวิธี deserialize เนื้อหา JSON เป็นชนิดไดนามิก C # 4 หรือไม่ DataContractJsonSerializerมันจะดีที่จะข้ามสร้างพวงของการเรียนเพื่อที่จะใช้


5
หากคุณต้องการบางสิ่งบางอย่าง 'แบบไดนามิก' ทำไมไม่ใช้อุปกรณ์ access-style ที่มาพร้อมกับตัวถอดรหัส JSON ส่วนใหญ่ที่ไม่ไปที่วัตถุเก่าธรรมดา? (เช่นมีความจำเป็นในการสร้างวัตถุ 'ไดนามิก' จริง ๆ หรือไม่?) json.orgมีลิงค์มากมายสำหรับการใช้งาน C # JSON

ฉันกำลังทำงานในโครงการที่พยายามทำให้การพึ่งพาจากภายนอกให้น้อยที่สุด ดังนั้นหากเป็นไปได้ที่บางสิ่งบางอย่างกับ. serializers สุทธิและประเภทที่จะเป็นที่ต้องการ แน่นอนว่าถ้าเป็นไปไม่ได้ฉันจะไป json.org ขอบคุณ!
jswanson

42
ฉันประหลาดใจจริงๆที่ทีม C # ได้เพิ่ม 'ไดนามิก' แต่ไม่มีวิธีใดใน CLR ในการแปลงวัตถุ JSON เป็นอินสแตนซ์คลาส CLR แบบไดนามิก
Frank Schwieterman

2
น่าเสียดายที่คำตอบที่ยอมรับไม่สามารถใช้งานได้ใน. NET 4 RTM ฉันโพสต์คำตอบที่ช่วยให้ฉันไปกับสิ่งนี้ซึ่งอาจเป็นประโยชน์กับผู้อื่น
Drew Noakes

(แม้ว่าจะปรากฏว่า Newtonsoft JSON.NET เข้ามาใกล้พอสมควร แต่ก็ไม่มีตัวอย่างที่ดีจริงๆ)
Hot Licks

คำตอบ:


659

หากคุณมีความสุขที่ได้พึ่งพาการSystem.Web.Helpersประชุมจากนั้นคุณสามารถใช้Jsonชั้นเรียน:

dynamic data = Json.Decode(json);

มันมาพร้อมกับกรอบงาน MVC เป็นการดาวน์โหลดเพิ่มเติมไปยังกรอบงาน. NET 4 อย่าลืมโหวตให้ Vlad ดูว่ามีประโยชน์หรือไม่! อย่างไรก็ตามหากคุณไม่สามารถสันนิษฐานได้ว่าสภาพแวดล้อมของไคลเอนต์นั้นรวมถึง DLL นี้ให้อ่านต่อไป


แนะนำวิธีการดีซีเรียลไลเซชั่นทางเลือกที่นี่ ฉันแก้ไขรหัสเล็กน้อยเพื่อแก้ไขข้อบกพร่องและให้เหมาะกับสไตล์การเขียนโค้ดของฉัน สิ่งที่คุณต้องมีคือรหัสนี้และการอ้างอิงSystem.Web.Extensionsจากโครงการของคุณ:

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
}

คุณสามารถใช้สิ่งนี้:

string json = ...;

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

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

ดังนั้นให้สตริง JSON:

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

รหัสต่อไปนี้จะทำงานในขณะใช้งานจริง:

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)

1
ฉันพบข้อผิดพลาดใน dynamic obj = serializer.Deserialize (json, typeof (object)); บอกว่าไม่มีการโอเวอร์โหลดสำหรับวิธีที่มี 2 ข้อโต้แย้ง .. ผิด dll หรืออะไร
Stewie Griffin

32
คุณสามารถใช้ System.Web.Helpers.Json - มันมีวิธีการถอดรหัสที่ส่งกลับวัตถุแบบไดนามิก ฉันโพสต์ข้อมูลนี้เป็นคำตอบด้วย
Vlad Iliescu

2
สิ่งนี้ช่วยฉันได้มากเช่นกัน แต่ฉันอยากรู้ว่าฉันควรทำอย่างไรถ้าฉันจำเป็นต้องใช้วิธีการ. จัดระเบียบใหม่ซึ่งในปัจจุบันมีเพียงการเผยแพร่ NotImplemented ข้อยกเว้น ... ฉันไม่คุ้นเคยกับคลาสที่ปิดผนึกและ / หรือบทคัดย่อที่ขยายออกไป ชั้นเรียน ใครช่วยชี้ฉันในทิศทางที่ถูกต้องได้ไหม
Cory W.

2
บางครั้งใน js คุณมีช่องที่มีตัวอักษรพิเศษเช่น "background-color" ในการเข้าถึงฟิลด์ดังกล่าวใน js คุณต้องทำ obj ["background-color"] ฉันจะเข้าถึงฟิลด์ดังกล่าวจาก c # หลังจากดีซีเรียลไลซ์ซิงไปยังวัตถุแบบไดนามิกได้อย่างไร ฉันไม่สามารถทำ obj.background-color แน่นอนและ obj ["background-color"] ดูเหมือนจะไม่ทำงาน มันจะดีถ้าวัตถุแบบไดนามิกสามารถเข้าถึงได้เป็นพจนานุกรมในเวลาเดียวกันเหมือนกับใน js
Radu Simionescu

2
@RaduSimionescu ฉันอาจจะสายไปหน่อย แต่นี่อาจช่วยผู้เยี่ยมชมในอนาคต ฉันมีปัญหาเดียวกันกับชื่อฟิลด์params(ซึ่งเป็นคำหลักใน C #) นอกจากนี้TryGetMemberคุณยังสามารถแทนที่TryGetIndexซึ่งจะช่วยให้คุณมีพฤติกรรมเช่นเดียวกับใน JS จากนั้นคุณสามารถทำobj["params"]หรือobj["background-color"]ชื่อเขตข้อมูลที่น่าอึดอัดใจ
Martin Ender

606

มันค่อนข้างง่ายโดยใช้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;

ยัง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;

เอกสารคู่มือ : การสืบค้น JSON ด้วยไดนามิก


9
@HotLicks: การไตร่ตรองแบบไดนามิกให้stuffทำดังนี้:foreach (Newtonsoft.Json.Linq.JProperty jproperty in stuff) { Console.WriteLine("jproperty.Name = {0}", jproperty.Name);}
Matthias

11
JsonConvert.DeserializeObject และ JObject.Parse แตกต่างกันอย่างไร คำตอบคือใช้พวกเขาทั้งสองในลักษณะเดียวกันเพื่อทำสิ่งเดียวกัน แต่ไม่ได้อธิบายความแตกต่าง
cja

7
@TomPeplow ลองนี่ มันไม่ได้ผลสำหรับฉัน มันบอกว่า "JObject ไม่ได้ใช้ 'ชื่อ'"
Lee Louviere

4
@cja ไม่แตกต่างกัน: stackoverflow.com/questions/23645034/ …
nawfal

8
ฉันทำงานนี้ไม่ได้ ฉันได้ทำให้ปัญหาแคบลงจนอยู่ในasyncวิธีการ ถ้าฉันทำให้วิธีการซิงโครนัสมันทำงานตามที่คาดไว้ แต่ให้วิธีการasyncและฉันไม่สามารถได้รับฉันเพิ่งได้รับdynamic หล่ออย่างชัดเจนไม่ทำอะไรเลยยังคงเป็นเพียงให้ฉันobject objectมีใครประสบปัญหานี้อีกหรือไม่
codeConcussion

295

คุณสามารถทำได้โดยใช้System.Web.Helpers.Json - เมธอด Decode ส่งคืนออบเจกต์แบบไดนามิกซึ่งคุณสามารถสำรวจตามที่คุณต้องการ

มันรวมอยู่ในชุดประกอบ System.Web.Helpers (.NET 4.0)

var dynamicObject = Json.Decode(jsonString);

25
FYI System.Web.Helpers.dll ต้องการ. net 4.0 แต่ไม่รวมอยู่ใน. net 4.0 สามารถติดตั้งได้กับ ASP.NET MVC 3
jbtule

7
คุณจะพบแอสเซมบลีนี้ในกลุ่มส่วนขยายภายใต้แอสเซมบลีใน Visual Studio 2012
W3Max

1
มีปัญหาอะไรบ้างในการใช้ไดนามิก? วิธีที่เราสามารถจัดการกับข้อยกเว้นอย่างมีประสิทธิภาพถ้าใส่ JSON ไม่ได้มีคุณสมบัติ ..
อุซามะห์คาลิล

5
หากคุณต้องการที่จะพิมพ์รูปแบบขอให้แน่ใจว่าใช้วิธีการ Json.Decode <T> (สตริง)
Mike

2
ในการเพิ่มห้องสมุดนี้ในโครงการของคุณ: stackoverflow.com/questions/8037895/…

80

.NET 4.0 มีไลบรารีในตัวเพื่อทำสิ่งนี้:

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

นี่เป็นวิธีที่ง่ายที่สุด


27
คุณเคยลองสิ่งนี้หรือไม่? มันกลับDictionary<string,object>มา ตัวอย่างของคุณจะไม่ส่งคืนวัตถุไดนามิก
sergiopereira

18
สิ่งนี้ใช้งานไม่ได้ แต่เพียงส่งคืนคำสั่งในรูปแบบไดนามิก
mattmanser

55
@ ปีเตอร์ลองฉันเชื่อว่าฉันล้มเหลวในการระบุกรณีของฉันอย่างชัดเจนเพื่อนรัก ให้ฉันพยายามแก้ไขข้อผิดพลาดของฉัน ฉันรู้ว่าแบบไดนามิกคืออะไร สิ่งนี้ไม่อนุญาตให้คุณส่งผ่านวัตถุ JSON และใช้ d.code คุณต้องทำ d ["code"] ค่าซึ่งไม่ใช่สิ่งที่คนส่วนใหญ่ต้องการคำตอบนี้เรารู้แล้วว่าจะทำอย่างไร รับพจนานุกรมและส่งไปยังแบบไดนามิกคือเสียเวลาทั้งหมด ฉันไม่เห็นด้วยอย่างเคารพคุณ
mattmanser

4
we already know how to get the dictionary and casting it to a dynamic@mattmanser, มันไม่จำเป็นต้องเป็นพจนานุกรม Json ยังมีรายการนอกเหนือจากพจนานุกรม และยังสามารถซ้อนรายการและพจนานุกรมได้อีกด้วย รหัสของฉันสามารถจัดการกับสถานการณ์เหล่านี้ทั้งหมด แต่วิธีการของคุณไม่สามารถ
ปีเตอร์ลอง

4
@attmanser ถูกต้อง; มันเป็นไปได้ที่จะใช้ IDynamicMetaObjectProvider(หรือใช้เช่นExpandoObject) ที่สามารถสกัดกั้นคุณสมบัติและค้นหามันในพจนานุกรมภายใน รวมกับการใช้dynamicรหัสอนุญาตเช่นd.codeจะใช้ มันไม่มีประโยชน์อะไรที่จะแปลงพจนานุกรมให้เป็นแบบไดนามิก
Stephen Drew

78

"ข้อมูล JSON สตริง" แบบง่ายไปยังวัตถุโดยไม่มีไฟล์ DLL ของบุคคลที่สาม:

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

หมายเหตุ: คุณสามารถใช้วัตถุที่กำหนดเองได้

Personel item = serializer.Deserialize<Personel>(getString);

4
รหัสไม่เข้าใจ นี่เป็นวิธีที่ง่ายที่สุดและไม่มีใครพูดถึงมัน
cikatomo

2
ใช่มันง่าย :) บางครั้งคุณจำเป็นต้องเป็นอันดับ แต่ไม่ต้องการที่จะรวม dll ส่วนที่ 3
อิบราฮิมÖzbölük

คุณสามารถทำอย่างละเอียดใน: วิธีแบบไดนามิกสามารถเข้าถึงวัตถุ deserialized ผ่าน: myObject["myprop"]? ฉันรู้ว่ามันทำในรันไทม์ แต่วิธีการเข้าถึงผ่านmyObject["myprop"]ถูกต้อง?
Royi Namir

1
คุณสามารถทำการดีซีเรียลไลซ์วัตถุของคุณเช่น Personel item = serializer.Deserialize <Personel> (getString); และถ้าคุณใช้ออบเจ็กต์ไดนามิกคุณสามารถใช้อาเรย์และทุกอย่างเป็นไปได้เหมือนทุกอ็อบเจ็ก
İbrahimÖzbölük

3
ในการใช้เนมสเปซ System.Web.Script.Serialization โครงการของคุณต้องมีการอ้างอิงถึง System.Web.Extensions
StilgarISCA

28

JsonFxสามารถทำการ deserialize เนื้อหา JSON เป็นวัตถุแบบไดนามิก

ซีเรียลไลซ์เป็น / จากประเภทไดนามิก (ค่าเริ่มต้นสำหรับ. 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]}

19

ฉันสร้าง DynamicJsonConverter เวอร์ชันใหม่ซึ่งใช้ Expando Objects ฉันใช้วัตถุ Expando เพราะฉันต้องการทำให้เป็นอนุกรมแบบไดนามิกกลับไปที่ JSON โดยใช้ 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) })); }
        }
    }
}


14

คุณสามารถบรรลุเป้าหมายนั้นได้ด้วยความช่วยเหลือของ Newtonsoft.Json ติดตั้ง Newtonsoft.Json จาก Nuget และ:

using Newtonsoft.Json;

dynamic results = JsonConvert.DeserializeObject<dynamic>(YOUR_JSON);

8

วิธีที่ง่ายที่สุดคือ:

เพียงแค่รวมไฟล์ DLLนี้

ใช้รหัสเช่นนี้:

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.

6

คุณสามารถขยาย JavaScriptSerializer เพื่อคัดลอกพจนานุกรมที่สร้างขึ้นเพื่อขยายวัตถุแบบเรียกซ้ำแล้วใช้แบบไดนามิก:

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;
    }
}

จากนั้นคุณเพียงแค่ต้องมีการใช้คำสั่งสำหรับ namespace ที่คุณกำหนดนามสกุลใน (พิจารณาเพียงกำหนดไว้ใน System.Web.Script.Serialization ... เคล็ดลับอื่นคือการไม่ใช้ namespace แล้วคุณไม่จำเป็นต้องใช้ งบเลย) และคุณสามารถใช้มันได้เช่น:

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

6

คุณสามารถใช้ได้ using Newtonsoft.Json

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

resolvedEvent.Event.Data คือการตอบสนองของฉันจากการเรียกกิจกรรมหลัก


6

ฉันใช้http://json2csharp.com/เพื่อรับคลาสที่แสดงถึงวัตถุ JSON

การป้อนข้อมูล:

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

เอาท์พุท:

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; }
}

หลังจากนั้นฉันใช้Newtonsoft.Jsonเพื่อเติมคลาส:

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);
        }
    }
}

คุณสามารถโทรแบบนี้:

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

string stringJson = JObjects.Get(jsonClass);

PS:

หากชื่อตัวแปร JSON ของคุณไม่ใช่ชื่อ C # ที่ถูกต้อง (ชื่อขึ้นต้นด้วย$) คุณสามารถแก้ไขได้ดังนี้:

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; }
}

5

เพื่อที่ฉันจะใช้ JSON.NET เพื่อแยกวิเคราะห์ระดับต่ำของสตรีม JSON แล้วสร้างลำดับชั้นวัตถุออกจากอินสแตนซ์ของExpandoObjectชั้นเรียน


5

ฉันใช้สิ่งนี้ในรหัสของฉันและมันก็ใช้ได้ดี

using System.Web.Script.Serialization;
JavaScriptSerializer oJS = new JavaScriptSerializer();
RootObject oRootObject = new RootObject();
oRootObject = oJS.Deserialize<RootObject>(Your JSon String);

1
แต่นั่นไม่ใช่คำถามที่ถาม มีความแตกต่างเมื่อคุณต้องระบุประเภทสำหรับทุกสตริง json และทำงานกับประเภทแบบไดนามิก
Illuminati

5

ดูบทความที่ฉันเขียนใน CodeProject ซึ่งตอบคำถามได้อย่างแม่นยำ:

ประเภทไดนามิกด้วย JSON.NET

มีวิธีมากเกินไปสำหรับการโพสต์ใหม่ทั้งหมดที่นี่และแม้แต่จุดที่น้อยลงเนื่องจากบทความนั้นมีไฟล์แนบกับไฟล์ต้นฉบับ / ไฟล์ที่ต้องการ


5

ตัวเลือกอื่นคือ"วาง JSON เป็นคลาส"เพื่อให้สามารถทำการ deserialised ได้ง่ายและรวดเร็ว

  1. เพียงคัดลอก JSON ทั้งหมดของคุณ
  2. ใน Visual Studio: คลิกแก้ไขวางแบบพิเศษวาง JSON เป็นคลาส

นี่คือคำอธิบายที่ดีกว่า n piccas ... 'วาง JSON เป็นคลาส' ใน ASP.NET และเครื่องมือเว็บ 2012.2 RC


สิ่งนี้ช่วยฉันได้มากเวลา! ควรเลือกให้เป็นคำตอบที่ดีที่สุด!
jsiot

4

การดีซีเรียลไลซ์ใน JSON.NET สามารถเป็นแบบไดนามิกโดยใช้JObjectคลาสซึ่งรวมอยู่ในไลบรารีนั้น สตริง JSON ของฉันแสดงถึงคลาสเหล่านี้:

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

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

ตอนนี้เรา deserialize สตริงโดยไม่มีการอ้างอิงคลาสข้างต้น:

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());

หรือถ้าคุณต้องการที่จะไปลึก:

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());

ดูโพสต์สำหรับตัวอย่างที่สมบูรณ์


วิธีการนี้อนุญาตให้ "traverse" เอกสาร jSON เพื่อให้คุณสามารถจัดการสถานการณ์ที่โครงสร้าง JSON ไม่เป็นที่รู้จักหรือตัวแปร (ตัวอย่างเช่น API จำนวนมากส่งคืนเอกสาร JSON ที่แตกต่างอย่างสิ้นเชิงเมื่อเกิดข้อผิดพลาด) มีห้องสมุดอื่น ๆ ที่อนุญาตให้ทำนอกเหนือจาก Newtonsoft.JSON (aka JSON.NET) หรือไม่
อเล็กซ์ 75


4

มีไลบรารี่ JSON ขนาดเล็กสำหรับ C # ที่เรียกว่า SimpleJson

รองรับ. NET 3.5+, Silverlight และ Windows Phone 7

รองรับไดนามิกสำหรับ. NET 4.0

นอกจากนี้ยังสามารถติดตั้งเป็นแพ็คเกจ NuGet ได้

Install-Package SimpleJson

4

ใช้ชุดข้อมูล (C #) กับ JavaScript ฟังก์ชั่นง่าย ๆ สำหรับการสร้างสตรีม JSON ด้วย DataSet input สร้างเนื้อหา JSON เช่น (ชุดข้อมูลหลายตาราง):

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

เพียงแค่ฝั่งไคลเอ็นต์ใช้ eval ตัวอย่างเช่น,

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}]]')

จากนั้นใช้:

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;
}

3

ในการรับ ExpandoObject

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

Container container = JsonConvert.Deserialize<Container>(jsonAsString, new ExpandoObjectConverter());

3

ลองสิ่งนี้:

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

3

วิธีแยกวิเคราะห์เนื้อหา JSON ง่าย ๆ ด้วยไดนามิก & JavaScriptSerializer

โปรดเพิ่มการอ้างอิงของSystem.Web.Extensionsและเพิ่มเนมสเปซนี้using System.Web.Script.Serialization;ที่ด้านบน:

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();
}

วิธีแยกวิเคราะห์ json & complex แบบซ้อนด้วย dynamic & JavaScriptSerializer

โปรดเพิ่มการอ้างอิงของSystem.Web.Extensionsและเพิ่มเนมสเปซนี้using System.Web.Script.Serialization;ที่ด้านบน:

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();
}

1

ด้วยCinchoo ETL - ไลบรารีโอเพนซอร์สพร้อมที่จะแยก JSON เป็นวัตถุแบบไดนามิก:

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);
    }
}

เอาท์พุท:

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

คำเตือน: ฉันเป็นผู้เขียนของห้องสมุดนี้


0

ลองด้วยวิธีนี้!

ตัวอย่าง 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"]
        }]

รหัส 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()}");
        }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.