Giải trừ JSON thành đối tượng động C #?


965

Có cách nào để giải tuần tự hóa nội dung JSON thành kiểu động C # 4 không? Sẽ tốt hơn nếu bỏ qua việc tạo ra một loạt các lớp để sử dụng DataContractJsonSerializer.


5
Nếu bạn muốn một cái gì đó 'động', tại sao không sử dụng các bộ truy cập kiểu get đi kèm với hầu hết các bộ giải mã JSON không đi đến đối tượng đơn giản? (ví dụ: có thực sự cần phải tạo đối tượng 'động' không?) json.org có một loạt các liên kết để triển khai C # JSON.

Tôi đang làm việc trong một dự án đang cố gắng giảm thiểu sự phụ thuộc bên ngoài. Vì vậy, nếu có thể với một cái gì đó với các bộ nối tiếp stock .net và các loại sẽ được ưa thích. Tất nhiên, nếu không thể, tôi sẽ đánh json.org. Cảm ơn!
jswanson

42
Tôi thực sự ngạc nhiên khi nhóm C # đã thêm 'động' nhưng sau đó CLR không có cách nào để chuyển đổi một đối tượng JSON thành một thể hiện của lớp CLR động.
Frank Schwieterman

2
Thật không may, câu trả lời được chấp nhận không hoạt động trong .NET 4 RTM. Tôi đã đăng một câu trả lời giúp tôi giải quyết vấn đề này có thể hữu ích cho người khác.
Drew Noakes

(Mặc dù có vẻ như Newtonsoft JSON.NET khá gần. Mặc dù vậy, không có ví dụ nào thực sự tốt cả.)
Hot Licks

Câu trả lời:


659

Nếu bạn hài lòng khi có sự phụ thuộc vào System.Web.Helpershội đồng, thì bạn có thể sử dụng Jsonlớp:

dynamic data = Json.Decode(json);

Nó được bao gồm trong khung MVC như là một bản tải xuống bổ sung cho khung .NET 4. Hãy chắc chắn cung cấp cho Vlad một upvote nếu điều đó hữu ích! Tuy nhiên nếu bạn không thể giả sử môi trường máy khách bao gồm DLL này, thì hãy đọc tiếp.


Một cách tiếp cận khử lưu huỳnh thay thế được đề xuất ở đây . Tôi đã sửa đổi mã một chút để sửa lỗi và phù hợp với phong cách mã hóa của tôi. Tất cả bạn cần là mã này và một tài liệu tham khảo System.Web.Extensionstừ dự án của bạn:

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
}

Bạn có thể sử dụng nó như thế này:

string json = ...;

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

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

Vì vậy, đã cho một chuỗi JSON:

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

Đoạn mã sau sẽ hoạt động trong thời gian chạy:

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
Tôi gặp lỗi trong động obj = serializer.Deserialize (json, typeof (object)); nói rằng không quá tải cho phương thức với 2 đối số..wrong dll hay gì?
Stewie Griffin

32
Bạn có thể sử dụng System.Web.Helpers.Json - nó cung cấp phương thức Giải mã trả về một đối tượng động. Tôi cũng đã đăng thông tin này như một câu trả lời.
Vlad Iliescu

2
Điều này cũng giúp tôi rất nhiều, nhưng tôi tò mò không biết nên làm gì nếu cần sử dụng phương thức .Serialize, hiện chỉ ném một NotImcellenceedException ... Tôi không quá quen thuộc với các lớp niêm phong và / hoặc tóm tắt mở rộng các lớp học. ai đó có thể chỉ cho tôi phương hướng đúng không?
Cory W.

2
đôi khi trong js bạn có các trường có ký tự đặc biệt như "màu nền". Để truy cập các trường như vậy trong js, bạn làm obj ["màu nền"]. Làm cách nào tôi có thể truy cập các trường như vậy từ c # sau khi giải tuần tự hóa sang đối tượng động? Dĩ nhiên, tôi không thể thực hiện obj.background-color và obj ["màu nền"] dường như không hoạt động. Sẽ thật tuyệt nếu đối tượng động cũng có thể được truy cập như một từ điển, đồng thời, giống hệt như trong js.
Radu Simionescu

2
@RaduSimionescu Tôi có thể hơi muộn, nhưng có lẽ điều này sẽ giúp khách truy cập trong tương lai. Tôi đã có cùng một vấn đề, chỉ với tên trường params(là một từ khóa trong C #). Ngoài ra, TryGetMemberbạn có thể ghi đè TryGetIndex, cung cấp cho bạn chính xác hành vi tương tự như trong JS. Sau đó, bạn có thể làm obj["params"]hoặc obj["background-color"]cho tên trường vụng về.
Martin Ender

606

Nó khá đơn giản khi sử dụng 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;

Ngoài ra 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;

Tài liệu: Truy vấn JSON bằng động


9
@HotLicks: Để hướng nội, stuffhãy làm điều gì đó như:foreach (Newtonsoft.Json.Linq.JProperty jproperty in stuff) { Console.WriteLine("jproperty.Name = {0}", jproperty.Name);}
Matthias

11
Sự khác biệt giữa JsonConvert.DeserializeObject và JObject.Pude là gì? Câu trả lời là sử dụng cả hai theo cùng một cách để làm cùng một việc nhưng không giải thích được sự khác biệt.
cja

7
@TomPeplow Đã thử điều này. Nó không làm việc cho tôi. Nó nói rằng "JObject không thực hiện 'Tên'".
Lee Louviere

4
@cja không có gì khác biệt: stackoverflow.com/questions/23645034/ từ
nawfal

8
Tôi không thể làm việc này. Tôi đã thu hẹp vấn đề xuống bên trong một asyncphương thức. Nếu tôi làm cho phương thức đồng bộ, nó hoạt động như mong đợi. Tuy nhiên, thực hiện phương pháp asyncvà tôi không thể có được dynamic, tôi chỉ nhận được một object. Đúc rõ ràng không làm gì, vẫn chỉ cho tôi một object. Có ai khác trải qua điều này?
codeConcussion

295

Bạn có thể thực hiện việc này bằng System.Web.Helpers.Json - phương thức Giải mã của nó trả về một đối tượng động mà bạn có thể duyệt qua tùy thích.

Nó được bao gồm trong hội đồng System.Web.Helpers (.NET 4.0).

var dynamicObject = Json.Decode(jsonString);

25
FYI System.Web.Helpers.dll yêu cầu .net 4.0 nhưng không được bao gồm trong .net 4.0. Nó có thể được cài đặt với ASP.NET MVC 3
jbtule

7
Bạn sẽ tìm thấy hội đồng này trong nhóm Tiện ích mở rộng trong Hội đồng trong Visual Studio 2012
W3Max

1
Bất kỳ vấn đề với việc sử dụng năng động? Làm cách nào chúng ta có thể xử lý các trường hợp ngoại lệ một cách hiệu quả nếu JSON đầu vào không chứa các thuộc tính ..
Usama Khalil

5
Nếu bạn muốn gõ mạnh mô hình thì hãy chắc chắn sử dụng phương thức Json.Decode <T> (chuỗi).
Mike

2
Để thêm thư viện này vào dự án của bạn: stackoverflow.com/questions/8037895/

80

.NET 4.0 có một thư viện tích hợp để thực hiện việc này:

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

Đây là cách đơn giản nhất.


27
bạn đã thử cái này chưa Nó trở lại Dictionary<string,object>. Trừ khi tôi thiếu một cái gì đó, ví dụ của bạn không trả về một đối tượng động.
sergiopereira

18
Điều này không hoạt động, nó chỉ trả lại một lệnh dưới dạng động
mattmanser

55
@Peter Long Tôi tin rằng tôi đã thất bại trong việc nêu rõ trường hợp của mình, anh bạn thân mến. Hãy để tôi cố gắng khắc phục lỗi của tôi. Tôi biết thế nào là năng động. Điều này không cho phép bạn truyền vào một đối tượng JSON và sử dụng d.code, bạn phải thực hiện d ["code"]. Giá trị, đó không phải là điều mà hầu hết mọi người tìm thấy câu trả lời này muốn, chúng tôi đã biết cách lấy từ điển và chuyển nó thành một động lực là một sự lãng phí hoàn toàn thời gian. Tôi tôn trọng không đồng ý, thưa ông.
mattmanser

4
@mattmanser , we already know how to get the dictionary and casting it to a dynamic. Nó không phải là một từ điển. Json cũng có danh sách bên cạnh từ điển. Và cũng có thể liệt kê danh sách và từ điển. Mã của tôi có thể xử lý tất cả các tình huống này. NHƯNG phương pháp của bạn KHÔNG THỂ.
Peter Long

4
@mattmanser đúng; có thể thực hiện IDynamicMetaObjectProvider(hoặc sử dụng ví dụ ExpandoObject) có khả năng chặn các thuộc tính và tra cứu chúng trong một từ điển nội bộ. Điều này kết hợp với việc sử dụng dynamicmã cho phép như d.codeđược sử dụng. Thật vô nghĩa khi bỏ từ điển thành động.
Stephen Drew

78

"Chuỗi dữ liệu JSON" đơn giản để phản đối mà không cần bất kỳ tệp DLL của bên thứ ba nào:

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

Lưu ý: Bạn cũng có thể sử dụng đối tượng tùy chỉnh của mình.

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

4
Id không nhận được nó. Đây là giải pháp đơn giản nhất và không ai đề cập đến nó.
cikatomo

2
vâng, nó đơn giản :) đôi khi bạn cần tuần tự hóa nhưng không muốn bao gồm phần 3 dll
İbrahim zbölük

Bạn có thể giải thích về: làm thế nào năng động có thể truy cập vào đối tượng DEserialized thông qua : myObject["myprop"]? Tôi biết nó được thực hiện trong thời gian chạy nhưng làm thế nào để truy cập nó myObject["myprop"]là hợp lệ?
Royi Namir

1
Bạn có thể giải tuần tự hóa đối tượng của mình như Personel item = serializer.Deserialize <Personel> (getString); và nếu bạn sử dụng đối tượng động, bạn cũng có thể sử dụng mảng và mọi thứ đều có thể như mọi đối tượng
İbrahim zbölük

3
Để sử dụng không gian tên System.Web.Script.Serialization, dự án của bạn cần tham chiếu đến System.Web.Extensions.
StilgarISCA

28

JsonFx có thể giải tuần tự hóa nội dung JSON thành các đối tượng động.

Nối tiếp đến / từ các loại động (mặc định cho .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

Tôi đã tạo một phiên bản mới của DynamicJsonConverter sử dụng Đối tượng Expando. Tôi đã sử dụng các đối tượng mở rộng, vì tôi muốn tuần tự hóa lại động vào JSON bằng 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) })); }
        }
    }
}

18

Một cách khác sử dụng Newtonsoft.Json :

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

14

Bạn có thể đạt được điều đó với sự giúp đỡ của Newtonsoft.Json. Cài đặt Newtonsoft.Json từ Nuget và:

using Newtonsoft.Json;

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

8

Cách đơn giản nhất là:

Chỉ cần bao gồm tập tin DLL này .

Sử dụng mã như thế này:

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

Bạn có thể mở rộng JavaScriptSerializer để sao chép đệ quy từ điển mà nó đã tạo để mở rộng (các) đối tượng và sau đó sử dụng chúng một cách linh hoạt:

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

Sau đó, bạn chỉ cần có một câu lệnh sử dụng cho không gian tên mà bạn đã xác định tiện ích mở rộng (xem xét chỉ xác định chúng trong System.Web.Script.Serialization ... một mẹo khác là không sử dụng một không gian tên, sau đó bạn không cần sử dụng tuyên bố ở tất cả) và bạn có thể tiêu thụ chúng như vậy:

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

Bạn có thể dùng using Newtonsoft.Json

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

resolvedEvent.Event.Data là phản hồi của tôi nhận được từ việc gọi sự kiện cốt lõi.


6

Tôi sử dụng http://json2csharp.com/ để lấy một lớp đại diện cho đối tượng JSON.

Đầu vào:

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

Đầu ra:

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

Sau đó tôi sử dụng Newtonsoft.Json để điền vào lớp:

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

Bạn có thể gọi nó như thế này:

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

string stringJson = JObjects.Get(jsonClass);

Tái bút

Nếu tên biến JSON của bạn không phải là tên C # hợp lệ (tên bắt đầu bằng $), bạn có thể sửa như thế này:

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

Vì vậy, tôi sẽ sử dụng JSON.NET để thực hiện phân tích cú pháp mức độ thấp của luồng JSON và sau đó xây dựng hệ thống phân cấp đối tượng ra khỏi các phiên bản của ExpandoObjectlớp.


5

Tôi đang sử dụng như thế này trong mã của tôi và nó hoạt động tốt

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

1
nhưng đó không phải là những gì câu hỏi đang hỏi về. có một sự khác biệt khi bạn phải chỉ định loại cho mỗi chuỗi json và làm việc với loại động.
Illuminati

5

Nhìn vào bài báo tôi đã viết trên CodeProject, một bài trả lời chính xác câu hỏi:

Các kiểu động với JSON.NET

Có quá nhiều cách để đăng lại tất cả ở đây, và thậm chí ít điểm hơn vì bài viết đó có tệp đính kèm với tệp nguồn / khóa bắt buộc.


5

Một tùy chọn khác là "Dán JSON dưới dạng các lớp" để có thể giải nén nhanh chóng và dễ dàng.

  1. Chỉ cần sao chép toàn bộ JSON của bạn
  2. Trong Visual Studio: Nhấp vào Chỉnh sửaDán Đặc biệtDán JSON dưới dạng các lớp

Dưới đây là một lời giải thích tốt hơn n piccas ... 'Dán JSON như các lớp' trong ASP.NET và các công cụ web 2012.2 RC


Điều này giúp tôi tiết kiệm rất nhiều thời gian! nên được chọn là câu trả lời tốt nhất!
jsiot

4

Việc khử lưu huỳnh trong JSON.NET có thể là động khi sử dụng JObjectlớp, được bao gồm trong thư viện đó. Chuỗi JSON của tôi đại diện cho các lớp này:

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

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

Bây giờ chúng tôi giải tuần tự hóa chuỗi mà KHÔNG tham chiếu các lớp trên:

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

Hoặc nếu bạn muốn đi sâu hơn:

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

Xem bài cho một ví dụ đầy đủ.


Cách tiếp cận này cho phép "duyệt" tài liệu jSON, để bạn có thể quản lý tình huống trong đó cấu trúc JSON không xác định hoặc biến (ví dụ: nhiều API trả về một tài liệu JSON hoàn toàn khác khi xảy ra lỗi). Có những thư viện khác cho phép làm điều đó, ngoài Newtonsoft.JSON (còn gọi là JSON.NET)?
Alex 75

4

Đối tượng bạn muốn DynamicJSONObject được bao gồm trong System.Web.Helpers.dll từ gói Trang web ASP.NET, một phần của WebMatrix.


4

Có một thư viện JSON nhẹ cho C # được gọi là SimpleJson .

Nó hỗ trợ .NET 3.5+, Silverlight và Windows Phone 7.

Nó hỗ trợ động cho .NET 4.0

Nó cũng có thể được cài đặt dưới dạng gói NuGet

Install-Package SimpleJson

4

Sử dụng tập dữ liệu (C #) với JavaScript. Một hàm đơn giản để tạo luồng JSON với đầu vào Dataset. Tạo nội dung JSON như (tập dữ liệu đa bảng):

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

Chỉ cần phía khách hàng, sử dụng eval. Ví dụ,

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

Sau đó sử dụng:

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

Để có được ExpandoObject:

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

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

3

Thử cái này:

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

3

Cách phân tích nội dung JSON dễ dàng với động & JavaScriptSerializer

Vui lòng thêm tham chiếu của System.Web.Extensions và thêm không gian tên này using System.Web.Script.Serialization;ở đầu:

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

Cách phân tích json lồng nhau & phức tạp với trình động & JavaScriptSerializer

Vui lòng thêm tham chiếu của System.Web.Extensions và thêm không gian tên này using System.Web.Script.Serialization;ở đầu:

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

Với Cinchoo ETL - một thư viện mã nguồn mở có sẵn để phân tích JSON thành một đối tượng động:

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

Đầu ra:

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

Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả của thư viện này.


0

Hãy thử cách này!

Ví dụ 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"]
        }]

Mã 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()}");
        }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.