Làm cách nào tôi có thể giải tuần tự JSON thành một Từ điển đơn giản <chuỗi, chuỗi> trong ASP.NET?


679

Tôi có một danh sách khóa / giá trị đơn giản trong JSON được gửi lại cho ASP.NET thông qua POST. Thí dụ:

{ "key1": "value1", "key2": "value2"}

TÔI KHÔNG HÃY THỬ TUYỆT VỜI VÀO ĐỐI TƯỢNG .NET MẠNH M TY

Tôi chỉ cần một Từ điển cũ đơn giản (Of String, String) hoặc một số từ tương đương (bảng băm, Từ điển (Of String, Object), StringDipedia cũ - địa ngục, một chuỗi các chuỗi 2 chiều sẽ phù hợp với tôi.

Tôi có thể sử dụng bất cứ thứ gì có sẵn trong ASP.NET 3.5, cũng như Json.NET phổ biến (mà tôi đã sử dụng để tuần tự hóa cho máy khách).

Rõ ràng cả hai thư viện JSON này đều không có khả năng rõ ràng này - chúng hoàn toàn tập trung vào việc khử lưu huỳnh dựa trên phản xạ thông qua các hợp đồng mạnh.

Có ý kiến ​​gì không?

Hạn chế:

  1. Tôi không muốn triển khai trình phân tích cú pháp JSON của riêng mình
  2. Không thể sử dụng ASP.NET 4.0
  3. Muốn tránh xa lớp ASP.NET cũ hơn, không dùng nữa cho JSON

1
re: giới hạn 3, JavaScriptSerizlizerđược sử dụng trong ASP.NET MVC và không còn bị phản đối nữa.
bdukes

17
thật khó tin khi tìm một cách đơn giản để chuyển đổi chuỗi json thành thứ gì đó tôi có thể dễ dàng sử dụng mà không cần lướt qua nhiều stackoverflow khác nhau. Thật dễ dàng trong các ngôn ngữ khác nhưng Java và C # dường như vượt ra ngoài để làm cho cuộc sống trở nên khó khăn.
user299709

Câu trả lời:


891

Json.NET làm điều này ...

string json = @"{""key1"":""value1"",""key2"":""value2""}";

var values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

Ví dụ khác: Nối tiếp Bộ sưu tập với Json.NET


9
Điều này cũng hoạt động khi giá trị của bạn là số nguyên. Chúng có tự động được chuyển thành 'chuỗi' không?
Highmastdon

58
@Highmastdon Không, không. Tôi đã tìm ra cách tốt nhất để giải tuần tự hóa vào từ điển là sử dụng dynamiclàm kiểu cho các giá trị:JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
Erik Schierboom

1
Đã thử một số câu trả lời trên trang này với cặp khóa / giá trị rất lộn xộn và JSON.NET là câu trả lời duy nhất mà tôi đã thử.
bnieland

15
Không hoạt động nếu bạn đang sử dụng một loạt các cặp giá trị chính trong json, [{key: "a", value: "1"}, {key: "b", value:"2"}]bạn phải làm một cái gì đó như thế này:var dict = JsonConvert.DeserializeObject<List<KeyValuePair<string, string>>>(json);
Adrian

8
Cũng không hoạt động nếu các giá trị là các đối tượng lồng nhau, bởi vì json.net tạo các giá trị đó dưới dạng JObjects
Kugel

100

Tôi đã phát hiện ra .NET có một cách dựng sẵn để truyền chuỗi JSON thành một Dictionary<String, Object>thông qua System.Web.Script.Serialization.JavaScriptSerializerkiểu trong tập hợp 3.5 System.Web.Extensions. Sử dụng phương pháp DeserializeObject(String).

Tôi tình cờ phát hiện ra điều này khi thực hiện một bài ajax (thông qua jquery) của loại nội dung 'application / json' cho Phương thức trang .net tĩnh và thấy rằng phương thức (có một tham số duy nhất của loại Object) đã nhận được từ điển này một cách kỳ diệu.


5
nhưng trình xây dựng trong javascriptserializer là buggier hơn json.net, giải pháp đó tốt hơn. Ví dụ: javascriptseralizer sẽ trả về null thay vì các chuỗi trống và hoàn toàn không hoạt động đối với các thuộc tính nullable, v.v.
pilavdzice

1
@pilavdzice Không đề cập đến những điều thú vị mà bạn có khi cố gắng phân tích ngày vì nó giả định định dạng ngày không chuẩn của MS.
Cơ bản

16
Ví dụ mã nhanh: var jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();theo sauDictionary<string, object> dict = (Dictionary<string, object>)jsSerializer.DeserializeObject(jsonString);
Nate Cook

6
Ưu điểm của ví dụ của Nate Cook trong một trường hợp đơn giản là tránh sự cần thiết của các DLL bên ngoài. Tôi đang truy cập API từ bảng điều khiển độc lập chỉ có thể dựa vào khung .Net.
Nick.T

@pilavdzice Bạn có thể đi sâu vào chi tiết hơn không? Tôi không thể tái sản xuất "trở lại null thay vì các chuỗi blank" điều, nó đã cho tôi một chuỗi giá trị trống choSomeData: ""
jrh

51

Đối với những người tìm kiếm trên internet và tình cờ thấy bài đăng này, tôi đã viết một bài đăng trên blog về cách sử dụng lớp JavaScriptSerializer.

Đọc thêm ... http://procbits.com/2011/04/21/quick-json-serializationdeserialization-in-c/

Đây là một ví dụ:

var json = "{\"id\":\"13\", \"value\": true}";
var jss = new JavaScriptSerializer();
var table = jss.Deserialize<dynamic>(json);
Console.WriteLine(table["id"]);
Console.WriteLine(table["value"]);

hm, tôi đã cố gắng giải pháp của bạn ... Tôi có json như thế này { "id": "13", "giá trị": true} và đối với tôi chỉ Dictionary <động> Tác phẩm giải pháp
Marko

ok Tôi đã tìm thấy vấn đề ở đâu ... bạn cần thêm [] sau khi khai báo từ điển để giải tuần tự hóa đúng cách ... Tôi đang thêm bình luận vào bài đăng trên blog của bạn quá ... chúc mừng;)
Marko

Tôi đã cập nhật câu trả lời của mình để phản ánh tập dữ liệu cụ thể của bạn. Nó hoạt động tốt với năng động.
JP Richardson

Tôi vừa viết một trình phân tích cú pháp JSON khác linh hoạt hơn một chút và hỗ trợ Silverlight: Procbits.com/2011/08/11/ mẹo
JP Richardson

41

Đã cố gắng không sử dụng bất kỳ triển khai JSON bên ngoài nào vì vậy tôi đã giải thích như thế này:

string json = "{\"id\":\"13\", \"value\": true}";

var serializer = new JavaScriptSerializer(); //using System.Web.Script.Serialization;

Dictionary<string, string> values = serializer.Deserialize<Dictionary<string, string>>(json);

6
Thêm tham chiếu System.Web.Extensions để sử dụng System.Web.Script
Patrick Cullen

1
Tôi thích câu trả lời này nhất vì nó đơn giản và sử dụng .NET System.Web.Script.Serialization. Nó chỉ hoạt động. Tôi thậm chí đã có thể sử dụng JSON "không hợp lệ" string json = "{'id':13, 'value': true}";.
styfle

Vì tò mò, có cùng một cách để giải trừ vào từ điển OrdinalIgnoreCase không?
batbaatar

38

Tôi đã có cùng một vấn đề, vì vậy tôi đã tự viết nó. Giải pháp này được phân biệt với các câu trả lời khác vì nó có thể giải thích lại thành nhiều cấp độ.

Chỉ cần gửi chuỗi JSON vào hàm deserializeToDixi, nó sẽ trả về Dictionary<string, object>đối tượng không được gõ mạnh .

Mã cũ

private Dictionary<string, object> deserializeToDictionary(string jo)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
    var values2 = new Dictionary<string, object>();
    foreach (KeyValuePair<string, object> d in values)
    {
        // if (d.Value.GetType().FullName.Contains("Newtonsoft.Json.Linq.JObject"))
        if (d.Value is JObject)
        {
            values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
        }
        else
        {
            values2.Add(d.Key, d.Value);
        }
    }
    return values2;
}

Ví dụ: Điều này sẽ trả về Dictionary<string, object>đối tượng của phản hồi JSON của Facebook.

Kiểm tra

private void button1_Click(object sender, EventArgs e)
{
    string responsestring = "{\"id\":\"721055828\",\"name\":\"Dasun Sameera Weerasinghe\",\"first_name\":\"Dasun\",\"middle_name\":\"Sameera\",\"last_name\":\"Weerasinghe\",\"username\":\"dasun\",\"gender\":\"male\",\"locale\":\"en_US\",  hometown: {id: \"108388329191258\", name: \"Moratuwa, Sri Lanka\",}}";
    Dictionary<string, object> values = deserializeToDictionary(responsestring);
}

Lưu ý: quê hương tiếp tục giải thích thành một Dictionary<string, object> đối tượng.

Cập nhật

Câu trả lời cũ của tôi hoạt động rất tốt nếu không có mảng trên chuỗi JSON. Điều này tiếp tục giải thích thêm vào List<object>nếu một phần tử là một mảng.

Chỉ cần gửi một chuỗi JSON vào hàm deserializeToDipediaOrList, nó sẽ trả về Dictionary<string, object>đối tượng không được gõ mạnh hoặc List<object>.

private static object deserializeToDictionaryOrList(string jo,bool isArray=false)
{
    if (!isArray)
    {
        isArray = jo.Substring(0, 1) == "[";
    }
    if (!isArray)
    {
        var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
        var values2 = new Dictionary<string, object>();
        foreach (KeyValuePair<string, object> d in values)
        {
            if (d.Value is JObject)
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
            }
            else if (d.Value is JArray)
            {
                values2.Add(d.Key, deserializeToDictionary(d.Value.ToString(), true));
            }
            else
            {
                values2.Add(d.Key, d.Value);
            }
        }
        return values2;
    }else
    {
        var values = JsonConvert.DeserializeObject<List<object>>(jo);
        var values2 = new List<object>();
        foreach (var d in values)
        {
            if (d is JObject)
            {
                values2.Add(deserializeToDictionary(d.ToString()));
            }
            else if (d is JArray)
            {
                values2.Add(deserializeToDictionary(d.ToString(), true));
            }
            else
            {
                values2.Add(d);
            }
        }
        return values2;
    }
}

@Jordan cảm ơn vì đã chỉ ra, tôi đã thực hiện một số sửa đổi cho mã này nhưng tôi không có nó ngay bây giờ. Mã này không xử lý các đối tượng JArray, tôi sẽ cập nhật mã khi tôi có nó.
Dasun

1
Không thành vấn đề. Tôi chỉ đề cập đến nó bởi vì việc tìm hiểu về isvà các asnhà khai thác đã giúp tôi rất nhiều và đơn giản hóa mã của riêng tôi.
Jordan

Nó hoạt động, nhưng không hiệu quả, vì nó gọi ToString và sau đó Deserialize lại. Nhìn vào câu trả lời của Falko dưới đây. Đó là giải tuần tự hóa chuỗi nguồn chỉ một lần.
Sergei Zinovyev

1
Câu trả lời của Falko chỉ hoạt động nếu bạn biết trước cấu trúc dữ liệu. Giải pháp này có thể sử dụng cho bất kỳ chuỗi JSON nào.
Dasun

16

Nếu bạn đang theo một cách tiếp cận nhẹ, không có thêm tài liệu tham khảo, có thể đoạn mã tôi vừa viết sẽ hoạt động (mặc dù tôi không thể đảm bảo 100% độ mạnh).

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

public Dictionary<string, object> ParseJSON(string json)
{
    int end;
    return ParseJSON(json, 0, out end);
}
private Dictionary<string, object> ParseJSON(string json, int start, out int end)
{
    Dictionary<string, object> dict = new Dictionary<string, object>();
    bool escbegin = false;
    bool escend = false;
    bool inquotes = false;
    string key = null;
    int cend;
    StringBuilder sb = new StringBuilder();
    Dictionary<string, object> child = null;
    List<object> arraylist = null;
    Regex regex = new Regex(@"\\u([0-9a-z]{4})", RegexOptions.IgnoreCase);
    int autoKey = 0;
    for (int i = start; i < json.Length; i++)
    {
        char c = json[i];
        if (c == '\\') escbegin = !escbegin;
        if (!escbegin)
        {
            if (c == '"')
            {
                inquotes = !inquotes;
                if (!inquotes && arraylist != null)
                {
                    arraylist.Add(DecodeString(regex, sb.ToString()));
                    sb.Length = 0;
                }
                continue;
            }
            if (!inquotes)
            {
                switch (c)
                {
                    case '{':
                        if (i != start)
                        {
                            child = ParseJSON(json, i, out cend);
                            if (arraylist != null) arraylist.Add(child);
                            else
                            {
                                dict.Add(key, child);
                                key = null;
                            }
                            i = cend;
                        }
                        continue;
                    case '}':
                        end = i;
                        if (key != null)
                        {
                            if (arraylist != null) dict.Add(key, arraylist);
                            else dict.Add(key, DecodeString(regex, sb.ToString()));
                        }
                        return dict;
                    case '[':
                        arraylist = new List<object>();
                        continue;
                    case ']':
                        if (key == null)
                        {
                            key = "array" + autoKey.ToString();
                            autoKey++;
                        }
                        if (arraylist != null && sb.Length > 0)
                        {
                            arraylist.Add(sb.ToString());
                            sb.Length = 0;
                        }
                        dict.Add(key, arraylist);
                        arraylist = null;
                        key = null;
                        continue;
                    case ',':
                        if (arraylist == null && key != null)
                        {
                            dict.Add(key, DecodeString(regex, sb.ToString()));
                            key = null;
                            sb.Length = 0;
                        }
                        if (arraylist != null && sb.Length > 0)
                        {
                            arraylist.Add(sb.ToString());
                            sb.Length = 0;
                        }
                       continue;
                    case ':':
                        key = DecodeString(regex, sb.ToString());
                        sb.Length = 0;
                        continue;
                }
            }
        }
        sb.Append(c);
        if (escend) escbegin = false;
        if (escbegin) escend = true;
        else escend = false;
    }
    end = json.Length - 1;
    return dict; //theoretically shouldn't ever get here
}
private string DecodeString(Regex regex, string str)
{
    return Regex.Unescape(regex.Replace(str, match => char.ConvertFromUtf32(Int32.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.HexNumber))));
}

[Tôi nhận ra rằng điều này vi phạm Giới hạn số 1 của OP, nhưng về mặt kỹ thuật, bạn đã không viết nó, tôi đã làm]


3
Đó là câu trả lời duy nhất làm việc cho Silverlight và không phụ thuộc! Silverlight không có JavascriptSerializer hoặc serializable. Và không phụ thuộc có nghĩa là không có Json.NET, RestSharp hoặc MiniJSON. Chỉ @DanCsharpster đã thử một giải pháp khả thi khác nhưng tiếc là nó không hoạt động với tôi như cách này.
Cœur

1
Có gì sai khi thêm một tham chiếu đến một cái gì đó đơn giản như JSON.NET? Có cần phải nhẹ đến mức bạn không thể tham khảo bất cứ điều gì? Tôi không nói rằng mã của bạn sẽ không hoạt động, nhưng bất cứ khi nào bạn tự cuộn, bạn rõ ràng có nguy cơ mã của bạn không mạnh mẽ, đối với những thứ như trường hợp cạnh hoặc nhanh như một thư viện được thử nghiệm như JSON.NET.
Dan Csharpster

1
Tự lăn lộn là một ý tưởng tồi khi bạn có một lựa chọn tốt. Tôi biết không có tình huống mà có được nhẹ. Và tôi thà có ít mã tối ưu dễ đọc và thay đổi.
Jordan

3
Ban đầu tôi đã viết đoạn mã đó bởi vì tôi không có sự thay thế nào. Hãy xem xét những thứ như Silverlight hoặc nhà cung cấp các loại khác nhau cho các sản phẩm Office, trong đó việc thêm các tham chiếu bên ngoài vào dự án là cực kỳ có vấn đề hoặc không thể.
khéo léo

Tôi biết nó một vài năm sau đó, nhưng đây vẫn là một câu hỏi rất hợp lệ. Đối với bất kỳ ai thắc mắc tại sao chúng tôi lại muốn đi nhẹ như vậy, nếu bạn đang làm việc với SQL CLR C #, chỉ có rất nhiều thư viện "an toàn" mà bạn có thể sử dụng và System.RunTime.Serializationkhông phải là một trong số đó, tiếc là JSON.NET phụ thuộc vào nó và do đó nó không thể được sử dụng. Cảm ơn dexy cho công việc xuất sắc của bạn, tôi đã dám cải thiện nó một chút để có thể giải tuần tự hóa các mảng, xem mã cập nhật trong câu trả lời của tôi ở đây .
Alberto Rechy

15

Tôi chỉ cần phân tích một từ điển lồng nhau , như

{
    "x": {
        "a": 1,
        "b": 2,
        "c": 3
    }
}

nơi JsonConvert.DeserializeObjectkhông giúp đỡ. Tôi tìm thấy cách tiếp cận sau:

var dict = JObject.Parse(json).SelectToken("x").ToObject<Dictionary<string, int>>();

Việc SelectTokencho phép bạn đào xuống trường mong muốn. Bạn thậm chí có thể chỉ định một đường dẫn muốn "x.y.z"bước sâu hơn vào đối tượng JSON.


JObject.Pude (json) .ToObject <Dictionary <Guid, List <int >>> () đã làm việc cho tôi trong kịch bản của tôi cảm ơn
geedubb

11

System.Text.Json

Điều này bây giờ có thể được thực hiện bằng cách sử dụng System.Text.Jsonđược tích hợp sẵn .net core 3.0. Bây giờ có thể giải tuần tự hóa JSON mà không cần sử dụng các thư viện của bên thứ ba.

var json = @"{""key1"":""value1"",""key2"":""value2""}";
var values = JsonSerializer.Deserialize<Dictionary<string, string>>(json);

Cũng có sẵn trong gói nu-get System.Text.Json nếu sử dụng .Net Standard hoặc .Net Framework.


1
Đúng! System.Text.Jsonlà cách để đi trong những ngày này.
mfluehr

2
Vâng, có vẻ đầy hứa hẹn! Tuy nhiên, lưu ý rằng phiên bản mặc định của .NET Core 3.1 của System.Text.Json không hỗ trợ khử từ điển với các khóa không phải chuỗi. Mặc dù OP của tôi là về chuỗi, nhưng thực tế bây giờ, tôi có rất nhiều phím Guid, vì vậy điều này "cắn" tôi khi cố gắng thực hiện chuyển đổi. Nó cũng không có tương đương với một số thuộc tính (bắt buộc, v.v.).
richardtallent

6

Mark Rendle đã đăng bài này dưới dạng một bình luận , tôi muốn đăng nó như một câu trả lời vì đó là giải pháp duy nhất đã hoạt động để trả lại thành công và kết quả json mã lỗi từ phản hồi reCaptcha của Google.

string jsonReponseString= wClient.DownloadString(requestUrl);    
IDictionary<string, object> dict = new JavaScriptSerializer().DeserializeObject(jsonReponseString) as IDictionary<string, object>;

Cảm ơn một lần nữa, Mark!


1
JavaScriptSerializer gần như không được dùng nữa. Tài liệu nói rằng chúng ta nên sử dụng JSON.NET ( docs.microsoft.com/en-us/dotnet/api/ mẹo )
Mario Lopez

Cũng tốt cho các ứng dụng biểu mẫu web cũ mà bạn không muốn bao gồm các phụ thuộc bổ sung.
Andrew Grothe

5

Chỉnh sửa: Điều này hoạt động, nhưng câu trả lời được chấp nhận bằng Json.NET thì đơn giản hơn nhiều. Để lại cái này trong trường hợp ai đó cần mã chỉ BCL.

Nó không được .NET framework hỗ trợ. Một giám sát rõ ràng - không phải ai cũng cần khử lưu huỳnh thành các đối tượng có thuộc tính được đặt tên. Vì vậy, cuối cùng tôi đã tự lăn lộn:

<Serializable()> Public Class StringStringDictionary
    Implements ISerializable
    Public dict As System.Collections.Generic.Dictionary(Of String, String)
    Public Sub New()
        dict = New System.Collections.Generic.Dictionary(Of String, String)
    End Sub
    Protected Sub New(info As SerializationInfo, _
          context As StreamingContext)
        dict = New System.Collections.Generic.Dictionary(Of String, String)
        For Each entry As SerializationEntry In info
            dict.Add(entry.Name, DirectCast(entry.Value, String))
        Next
    End Sub
    Public Sub GetObjectData(info As SerializationInfo, context As StreamingContext) Implements ISerializable.GetObjectData
        For Each key As String in dict.Keys
            info.AddValue(key, dict.Item(key))
        Next
    End Sub
End Class

Được gọi với:

string MyJsonString = "{ \"key1\": \"value1\", \"key2\": \"value2\"}";
System.Runtime.Serialization.Json.DataContractJsonSerializer dcjs = new
  System.Runtime.Serialization.Json.DataContractJsonSerializer(
    typeof(StringStringDictionary));
System.IO.MemoryStream ms = new
  System.IO.MemoryStream(Encoding.UTF8.GetBytes(MyJsonString));
StringStringDictionary myfields = (StringStringDictionary)dcjs.ReadObject(ms);
Response.Write("Value of key2: " + myfields.dict["key2"]);

Xin lỗi vì sự pha trộn của C # và VB.NET.


2
[TestMethod] void void TestSimpleObject () {const chuỗi json = @ "{" "Tên" ":" "Bob" "," "Tuổi" ": 42}"; var dict = new JavaScriptSerializer (). DeserializeObject (json) là IDadata <string, object>; Khẳng định.IsNotNull (dict); Assert.IsTrue (dict.ContainsKey ("Tên")); Assert.AreEqual ("Bob", dict ["Tên"]); Assert.IsTrue (dict.ContainsKey ("Tuổi")); Assert.AreEqual (42, dict ["Tuổi"]); }
Đánh dấu Rendle

1
Cái này thật tuyệt. Giúp triển khai dịch vụ WCF có giao diện sử dụng JSON với các máy khách dựa trên trình duyệt.
Anton

@Mark Rendle: Việc triển khai của bạn rất đơn giản và là cách duy nhất đã làm việc cho tôi cho đến khi nhận được cả kết quả json thành công và mã lỗi. Tôi đã thử nhiều giải pháp, vì vậy cảm ơn bạn đã đăng nó như một bình luận. Nó nên là câu trả lời.
Bryan

5

Tôi đã thêm vào mã được gửi bởi jSnake04 và Dasun ở đây. Tôi đã thêm mã để tạo danh sách các đối tượng từ các JArrayphiên bản. Nó có đệ quy hai chiều nhưng vì nó hoạt động trên một mô hình cây cố định, hữu hạn, không có nguy cơ tràn ngăn xếp trừ khi dữ liệu rất lớn.

/// <summary>
/// Deserialize the given JSON string data (<paramref name="data"/>) into a
///   dictionary.
/// </summary>
/// <param name="data">JSON string.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(string data)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(data);

    return DeserializeData(values);
}

/// <summary>
/// Deserialize the given JSON object (<paramref name="data"/>) into a dictionary.
/// </summary>
/// <param name="data">JSON object.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(JObject data)
{
    var dict = data.ToObject<Dictionary<String, Object>>();

    return DeserializeData(dict);
}

/// <summary>
/// Deserialize any elements of the given data dictionary (<paramref name="data"/>) 
///   that are JSON object or JSON arrays into dictionaries or lists respectively.
/// </summary>
/// <param name="data">Data dictionary.</param>
/// <returns>Deserialized dictionary.</returns>
private IDictionary<string, object> DeserializeData(IDictionary<string, object> data)
{
    foreach (var key in data.Keys.ToArray()) 
    {
        var value = data[key];

        if (value is JObject)
            data[key] = DeserializeData(value as JObject);

        if (value is JArray)
            data[key] = DeserializeData(value as JArray);
    }

    return data;
}

/// <summary>
/// Deserialize the given JSON array (<paramref name="data"/>) into a list.
/// </summary>
/// <param name="data">Data dictionary.</param>
/// <returns>Deserialized list.</returns>
private IList<Object> DeserializeData(JArray data)
{
    var list = data.ToObject<List<Object>>();

    for (int i = 0; i < list.Count; i++)
    {
        var value = list[i];

        if (value is JObject)
            list[i] = DeserializeData(value as JObject);

        if (value is JArray)
            list[i] = DeserializeData(value as JArray);
    }

    return list;
}

4

Tôi đã thêm một kiểm tra cho các giá trị null trong JSON cho câu trả lời khác

Tôi đã có cùng một vấn đề vì vậy tôi đã tự viết điều này. Giải pháp này được phân biệt với các câu trả lời khác vì nó có thể giải thích lại thành nhiều cấp độ.

Chỉ cần gửi chuỗi json vào hàm deserializeToDixi, nó sẽ trả về Dictionary<string, object>đối tượng không được gõ mạnh .

private Dictionary<string, object> deserializeToDictionary(string jo)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(jo);
    var values2 = new Dictionary<string, object>();
    foreach (KeyValuePair<string, object> d in values)
    {
        if (d.Value != null && d.Value.GetType().FullName.Contains("Newtonsoft.Json.Linq.JObject"))
        {
            values2.Add(d.Key, deserializeToDictionary(d.Value.ToString()));
        }
        else
        {
            values2.Add(d.Key, d.Value);
        }
    }
    return values2;
}

Ví dụ: Điều này sẽ trả về Dictionary<string, object>đối tượng của phản hồi JSON của Facebook.

private void button1_Click(object sender, EventArgs e)
{
    string responsestring = "{\"id\":\"721055828\",\"name\":\"Dasun Sameera
        Weerasinghe\",\"first_name\":\"Dasun\",\"middle_name\":\"Sameera\",\"last_name\":\"Weerasinghe\",\"username\":\"dasun\",\"gender\":\"male\",\"locale\":\"en_US\",
        hometown: {id: \"108388329191258\", name: \"Moratuwa, Sri Lanka\",}}";
    Dictionary<string, object> values = deserializeToDictionary(responsestring);
}

Lưu ý: quê hương tiếp tục khử lưu huỳnh thành một Dictionary<string, object>đối tượng.


1
+1 Như tôi đã nói với Dasun ở trên. Bạn chỉ có thể kiểm tra xem d.Value is JObject. Bạn không phải trải qua sự phản ánh để kiểm tra các loại. Và với istoán tử, bạn không cần kiểm tra null. Nó trả về false nếu đối tượng là null.
Jordan

3

Dường như tất cả các câu trả lời ở đây chỉ giả sử bạn có thể lấy chuỗi nhỏ đó ra khỏi một vật thể lớn hơn ... đối với những người muốn đơn giản hóa giải thích một đối tượng lớn với một từ điển như vậy ở đâu đó trong ánh xạ và những người đang sử dụng System.Runtime.Serialization.Jsonhệ thống DataContract, đây một giải pháp:

Một câu trả lời trên gis.stackexchange.com đã có liên kết thú vị này . Tôi đã phải khôi phục nó với archive.org, nhưng nó cung cấp một giải pháp khá hoàn hảo: một IDataContractSurrogatelớp tùy chỉnh trong đó bạn thực hiện chính xác các kiểu của riêng bạn. Tôi đã có thể mở rộng nó một cách dễ dàng.

Tôi đã thực hiện một loạt các thay đổi trong đó, mặc dù. Vì nguồn ban đầu không còn nữa, tôi sẽ đăng toàn bộ lớp ở đây:

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;

namespace JsonTools
{
    /// <summary>
    /// Allows using Dictionary&lt;String,String&gt; and Dictionary&lt;String,Boolean&gt; types, and any others you'd like to add.
    /// Source: https://web.archive.org/web/20100317222656/my6solutions.com/post/2009/06/30/DataContractSerializer-DataContractJsonSerializer-JavaScriptSerializer-XmlSerializer-for-serialization.aspx
    /// </summary>
    public class JsonSurrogate : IDataContractSurrogate
    {
        /// <summary>
        /// Deserialize an object with added support for the types defined in this class.
        /// </summary>
        /// <typeparam name="T">Contract class</typeparam>
        /// <param name="json">JSON String</param>
        /// <param name="encoding">Text encoding</param>
        /// <returns>The deserialized object of type T</returns>
        public static T Deserialize<T>(String json, Encoding encoding)
        {
            if (encoding == null)
                encoding = new UTF8Encoding(false);
            DataContractJsonSerializer deserializer = new DataContractJsonSerializer(
                typeof(T), new Type[0], int.MaxValue, true, new JsonSurrogate(), false);
            using (MemoryStream stream = new MemoryStream(encoding.GetBytes(json)))
            {
                T result = (T)deserializer.ReadObject(stream);
                return result;
            }
        }

        // make sure all values in this are classes implementing JsonSurrogateObject.
        private static Dictionary<Type, Type> KnownTypes = 
            new Dictionary<Type, Type>()
            {
                {typeof(Dictionary<String, String>), typeof(SSDictionary)},
                {typeof(Dictionary<String, Boolean>), typeof(SBDictionary)}
            };

        #region Implemented surrogate dictionary classes

        [Serializable]
        public class SSDictionary : SurrogateDictionary<String>
        {
            public SSDictionary() : base() {}
            protected SSDictionary (SerializationInfo info, StreamingContext context) : base(info, context) {}
        }
        [Serializable]
        public class SBDictionary : SurrogateDictionary<Boolean>
        {
            public SBDictionary() : base() {}
            protected SBDictionary (SerializationInfo info, StreamingContext context) : base(info, context) {}
        }

        #endregion

        /// <summary>Small interface to easily extract the final value from the object.</summary>
        public interface JsonSurrogateObject
        {
            Object DeserializedObject { get; }
        }

        /// <summary>
        /// Class for deserializing any simple dictionary types with a string as key.
        /// </summary>
        /// <typeparam name="T">Any simple type that will be deserialized correctly.</typeparam>
            [Serializable]
        public abstract class SurrogateDictionary<T> : ISerializable, JsonSurrogateObject
        {
            public Object DeserializedObject { get { return dict; } }
            private Dictionary<String, T> dict;

            public SurrogateDictionary()
            {
                dict = new Dictionary<String, T>();
            }

            // deserialize
            protected SurrogateDictionary(SerializationInfo info, StreamingContext context)
            {
                dict = new Dictionary<String, T>();
                foreach (SerializationEntry entry in info)
                {
                    // This cast will only work for base types, of course.
                    dict.Add(entry.Name, (T)entry.Value);
                }
            }
            // serialize
            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                foreach (String key in dict.Keys)
                {
                    info.AddValue(key, dict[key]);
                }
            }

        }

        /// <summary>
            /// Uses the KnownTypes dictionary to get the surrogate classes.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Type GetDataContractType(Type type)
        {
            Type returnType;
            if (KnownTypes.TryGetValue(type, out returnType))
            {
                return returnType;
            }
            return type;
        }

        public object GetObjectToSerialize(object obj, Type targetType)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        ///     Gets the object out of the surrogate datacontract object. This function is the reason all surrogate objects need to implement the JsonSurrogateObject class.
        /// </summary>
        /// <param name="obj">Result of the deserialization</param>
        /// <param name="targetType">Expected target type of the deserialization</param>
        /// <returns></returns>
        public object GetDeserializedObject(object obj, Type targetType)
        {
            if (obj is JsonSurrogateObject)
            {
                return ((JsonSurrogateObject)obj).DeserializedObject;
            }
            return obj;
        }

        public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
        {
            return null;
        }

        #region not implemented

        public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
        {
            throw new NotImplementedException();
        }

        public object GetCustomDataToExport(Type clrType, Type dataContractType)
        {
            throw new NotImplementedException();
        }

        public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
        {
            throw new NotImplementedException();
        }

        public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}

Để thêm các loại được hỗ trợ mới vào lớp, bạn chỉ cần thêm lớp của mình, cung cấp cho nó các hàm tạo và hàm đúng (xem SurrogateDictionaryví dụ), đảm bảo rằng nó kế thừa JsonSurrogateObjectvà thêm ánh xạ kiểu của nó vào KnownTypestừ điển. SurrogateDixi đi kèm có thể dùng làm cơ sở cho bất kỳ Dictionary<String,T>loại nào trong đó T là bất kỳ loại nào giải nén chính xác.

Gọi nó là rất đơn giản:

MyObjtype newObj = JsonSurrogate.Deserialize<MyObjtype>(jsonStr, encoding);

Lưu ý rằng vì một số lý do, điều này gặp sự cố khi sử dụng các chuỗi khóa có chứa khoảng trắng; họ chỉ đơn giản là không có mặt trong danh sách cuối cùng. Có thể chỉ đơn giản là nó chống lại thông số kỹ thuật của json và api mà tôi đang gọi được thực hiện kém, làm phiền bạn; Tôi không biết. Dù sao, tôi đã giải quyết điều này bằng cách thay thế chúng bằng dấu gạch dưới trong dữ liệu json thô và sửa từ điển sau khi khử lưu huỳnh.


Nhân tiện, vì một số lý do kỳ dị, Mono dường như gặp khó khăn khi chạy thứ này ...
Nyerguds

Cảm ơn bạn đã chia sẻ, thật không may, giải pháp này không hỗ trợ các loại không nguyên thủy và không có cách nào để có được giá trị thô, vì vậy bạn có thể tự xây dựng nó. Nếu tôi đăng ký loại tùy chỉnh của mình trong KnownTypes và sử dụng nó trong từ điển, nó sẽ gọi từ điển trước, tôi sẽ mong nó bắt đầu phân tích từ dưới lên trên từ các loại từ xa nhất, đến các loại phức tạp hơn.
Ivan Leonenko

Vâng, câu hỏi chỉ hỏi về Dictionary<String,String>. Thành thật tôi không bao giờ thử khử lưu huỳnh các loại phức tạp với hệ thống này.
Nyerguds

3

Dựa trên ý kiến trên hãy thửJsonConvert.DeserializeObject<Dictionary<string,dynamic>>(json)

var json = @"{""key1"":1,""key2"":""value2"", ""object1"":{""property1"":""value1"",""property2"":[2,3,4,5,6,7]}}";
var parsedObject = JsonConvert.DeserializeObject<Dictionary<string,dynamic>>(json);

dường như làm việc ngay cả đối với các đối tượng và danh sách phức tạp.


1

Tôi chỉ thực hiện điều này trong RestSharp . Bài đăng này rất hữu ích cho tôi.

Ngoài mã trong liên kết, đây là mã của tôi. Bây giờ tôi nhận được một Dictionarykết quả khi tôi làm một cái gì đó như thế này:

var jsonClient = new RestClient(url.Host);
jsonClient.AddHandler("application/json", new DynamicJsonDeserializer());
var jsonRequest = new RestRequest(url.Query, Method.GET);
Dictionary<string, dynamic> response = jsonClient.Execute<JObject>(jsonRequest).Data.ToObject<Dictionary<string, dynamic>>();

Hãy chú ý đến loại JSON mà bạn mong đợi - trong trường hợp của tôi, tôi đã truy xuất một đối tượng với một số thuộc tính. Trong liên kết đính kèm, tác giả đã lấy một danh sách.


1

Cách tiếp cận của tôi trực tiếp giải tuần tự hóa cho IDadata, mà không có JObject hoặc ExpandObject ở giữa. Mã này sử dụng trình chuyển đổi, về cơ bản được sao chép từ lớp ExpandoObjectConverter được tìm thấy trong mã nguồn JSON.NET, nhưng sử dụng IDadata thay vì ExpandoObject.

Sử dụng:

var settings = new JsonSerializerSettings()
{
    Converters = { new DictionaryConverter() },
};
var result = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, settings);

Mã số:

// based on ExpandoObjectConverter, but using arrays instead of IList, to behave similar to System.Web.Script.Serialization.JavaScriptSerializer
public class DictionaryConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return ReadValue(reader);
    }

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IDictionary<string, object>));
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    private object ReadValue(JsonReader reader)
    {
        while (reader.TokenType == JsonToken.Comment)
        {
            if (!reader.Read())
                throw JsonSerializationExceptionCreate(reader, "Unexpected end when reading IDictionary<string, object>.");
        }

        switch (reader.TokenType)
        {
            case JsonToken.StartObject:
                return ReadObject(reader);
            case JsonToken.StartArray:
                return ReadList(reader);
            default:
                if (IsPrimitiveToken(reader.TokenType))
                    return reader.Value;

                throw JsonSerializationExceptionCreate(reader, string.Format(CultureInfo.InvariantCulture, "Unexpected token when converting IDictionary<string, object>: {0}", reader.TokenType));
        }
    }

    private object ReadList(JsonReader reader)
    {
        List<object> list = new List<object>();

        while (reader.Read())
        {
            switch (reader.TokenType)
            {
                case JsonToken.Comment:
                    break;
                default:
                    object v = ReadValue(reader);

                    list.Add(v);
                    break;
                case JsonToken.EndArray:
                    return list;
            }
        }

        throw JsonSerializationExceptionCreate(reader, "Unexpected end when reading IDictionary<string, object>.");
    }

    private object ReadObject(JsonReader reader)
    {
        IDictionary<string, object> dictionary = new Dictionary<string, object>();
        while (reader.Read())
        {
            switch (reader.TokenType)
            {
                case JsonToken.PropertyName:
                    string propertyName = reader.Value.ToString();

                    if (!reader.Read())
                        throw JsonSerializationExceptionCreate(reader, "Unexpected end when reading IDictionary<string, object>.");

                    object v = ReadValue(reader);

                    dictionary[propertyName] = v;
                    break;
                case JsonToken.Comment:
                    break;
                case JsonToken.EndObject:
                    return dictionary;
            }
        }

        throw JsonSerializationExceptionCreate(reader, "Unexpected end when reading IDictionary<string, object>.");
    }

    //based on internal Newtonsoft.Json.JsonReader.IsPrimitiveToken
    internal static bool IsPrimitiveToken(JsonToken token)
    {
        switch (token)
        {
            case JsonToken.Integer:
            case JsonToken.Float:
            case JsonToken.String:
            case JsonToken.Boolean:
            case JsonToken.Undefined:
            case JsonToken.Null:
            case JsonToken.Date:
            case JsonToken.Bytes:
                return true;
            default:
                return false;
        }
    }

    // based on internal Newtonsoft.Json.JsonSerializationException.Create
    private static JsonSerializationException JsonSerializationExceptionCreate(JsonReader reader, string message, Exception ex = null)
    {
        return JsonSerializationExceptionCreate(reader as IJsonLineInfo, reader.Path, message, ex);
    }

    // based on internal Newtonsoft.Json.JsonSerializationException.Create
    private static JsonSerializationException JsonSerializationExceptionCreate(IJsonLineInfo lineInfo, string path, string message, Exception ex)
    {
        message = JsonPositionFormatMessage(lineInfo, path, message);

        return new JsonSerializationException(message, ex);
    }

    // based on internal Newtonsoft.Json.JsonPosition.FormatMessage
    internal static string JsonPositionFormatMessage(IJsonLineInfo lineInfo, string path, string message)
    {
        if (!message.EndsWith(Environment.NewLine))
        {
            message = message.Trim();

            if (!message.EndsWith(".", StringComparison.Ordinal))
                message += ".";

            message += " ";
        }

        message += string.Format(CultureInfo.InvariantCulture, "Path '{0}'", path);

        if (lineInfo != null && lineInfo.HasLineInfo())
            message += string.Format(CultureInfo.InvariantCulture, ", line {0}, position {1}", lineInfo.LineNumber, lineInfo.LinePosition);

        message += ".";

        return message;
    }
}

1

Bạn có thể sử dụng Tiny-JSON

string json = "{\"key1\":\"value1\", \"key2\":\"value2\"}";
IDictionary<string, string> dict = Tiny.Json.Decode<Dictionary<string, string>>(json);

1

Một chút muộn của trò chơi, nhưng không phải là các giải pháp trên chỉ cho tôi theo hướng của một .NET đơn giản và đơn giản, không có giải pháp json.net. Vì vậy, đây là, kết thúc rất đơn giản. Bên dưới một ví dụ đầy đủ về cách nó được thực hiện với tuần tự hóa .NET Json tiêu chuẩn, ví dụ này có từ điển cả trong đối tượng gốc và trong các đối tượng con.

Viên đạn vàng là con mèo này, phân tích các thiết lập làm tham số thứ hai cho bộ nối tiếp:

DataContractJsonSerializerSettings settings =
                       new DataContractJsonSerializerSettings();
                    settings.UseSimpleDictionaryFormat = true;

Mã đầy đủ bên dưới:

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

    namespace Kipon.dk
    {
        public class JsonTest
        {
            public const string EXAMPLE = @"{
                ""id"": ""some id"",
                ""children"": {
                ""f1"": {
                    ""name"": ""name 1"",
                    ""subs"": {
                    ""1"": { ""name"": ""first sub"" },
                    ""2"": { ""name"": ""second sub"" }
                    }
                },
                ""f2"": {
                    ""name"": ""name 2"",
                    ""subs"": {
                    ""37"": { ""name"":  ""is 37 in key""}
                    }
                }
                }
            }
            ";

            [DataContract]
            public class Root
            {
                [DataMember(Name ="id")]
                public string Id { get; set; }

                [DataMember(Name = "children")]
                public Dictionary<string,Child> Children { get; set; }
            }

            [DataContract]
            public class Child
            {
                [DataMember(Name = "name")]
                public string Name { get; set; }

                [DataMember(Name = "subs")]
                public Dictionary<int, Sub> Subs { get; set; }
            }

            [DataContract]
            public class Sub
            {
                [DataMember(Name = "name")]
                public string Name { get; set; }
            }

            public static void Test()
            {
                var array = System.Text.Encoding.UTF8.GetBytes(EXAMPLE);
                using (var mem = new System.IO.MemoryStream(array))
                {
                    mem.Seek(0, System.IO.SeekOrigin.Begin);
                    DataContractJsonSerializerSettings settings =
                       new DataContractJsonSerializerSettings();
                    settings.UseSimpleDictionaryFormat = true;

                    var ser = new DataContractJsonSerializer(typeof(Root), settings);
                    var data = (Root)ser.ReadObject(mem);
                    Console.WriteLine(data.Id);
                    foreach (var childKey in data.Children.Keys)
                    {
                        var child = data.Children[childKey];
                        Console.WriteLine(" Child: " + childKey + " " + child.Name);
                        foreach (var subKey in child.Subs.Keys)
                        {
                            var sub = child.Subs[subKey];
                            Console.WriteLine("   Sub: " + subKey + " " + sub.Name);
                        }
                    }
                }
            }
        }
    }

0

Thật khó chịu, nếu bạn muốn sử dụng các chất kết dính mô hình mặc định, có vẻ như bạn sẽ phải sử dụng các giá trị chỉ số bằng số như một dạng POST.

Xem đoạn trích sau từ bài viết này http://msdn.microsoft.com/en-us/magazine/hh781022.aspx :

Mặc dù nó hơi phản trực giác, nhưng các yêu cầu JSON cũng có cùng yêu cầu, chúng cũng phải tuân thủ cú pháp đặt tên bài đăng mẫu. Lấy ví dụ, tải trọng JSON cho bộ sưu tập Unitprice trước đó. Cú pháp mảng JSON thuần cho dữ liệu này sẽ được biểu diễn dưới dạng:

[ 
  { "Code": "USD", "Amount": 100.00 },
  { "Code": "EUR", "Amount": 73.64 }
]

Tuy nhiên, các nhà cung cấp giá trị mặc định và các ràng buộc mô hình yêu cầu dữ liệu phải được biểu diễn dưới dạng bài đăng dạng JSON:

{
  "UnitPrice[0].Code": "USD",
  "UnitPrice[0].Amount": 100.00,

  "UnitPrice[1].Code": "EUR",
  "UnitPrice[1].Amount": 73.64
}

Kịch bản thu thập đối tượng phức tạp có lẽ là một trong những kịch bản có vấn đề rộng rãi nhất mà các nhà phát triển gặp phải vì cú pháp không nhất thiết phải rõ ràng đối với tất cả các nhà phát triển. Tuy nhiên, một khi bạn học được cú pháp tương đối đơn giản để đăng các bộ sưu tập phức tạp, các kịch bản này trở nên dễ xử lý hơn nhiều.


0

Tôi muốn đề nghị sử dụng System.Runtime.Serialization.Jsonđó là một phần của .NET 4.5.

[DataContract]
public class Foo
{
   [DataMember(Name = "data")]
   public Dictionary<string,string> Data { get; set; }
}

Sau đó sử dụng nó như thế này:

var serializer = new DataContractJsonSerializer(typeof(List<Foo>));
var jsonParams = @"{""data"": [{""Key"":""foo"",""Value"":""bar""}] }";
var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonParams));

var obj = serializer.ReadObject(stream);
Console.WriteLine(obj);

Nối tiếp được định nghĩa ở đâu?
bnieland

..và Category3MeasureModel là gì? Không có lượt truy cập trên Google.
bnieland

1
Đó chỉ là lớp mô hình mà tôi đang tuần tự hóa cho dự án của mình. Nó được cho là lớp Foo đó, nhưng tôi đã lấy lại toàn bộ phần từ mã sản xuất. Bạn nên tạo riêng của bạn, như lớp Foo của tôi. Tôi đổi tên nó thành Foo để làm cho nó đơn giản hơn. Nó chỉ là một lớp các thuộc tính hoặc các trường mà bạn muốn nối tiếp thành json và ngược lại.
Dan Csharpster

1
@DanCsharpster Với bản sao chính xác của mã của bạn, tôi nhận được, trên Windows Phone 8.1 Silverlight: `Một ngoại lệ của loại 'System.Security.SecurityException' đã xảy ra trong System.ServiceModel.Web.ni.dll nhưng không được xử lý trong người dùng mã Thông tin bổ sung: Loại hợp đồng dữ liệu 'MyApp.Foo' không thể được hủy bỏ vì thành viên 'Dữ liệu' không công khai. Làm cho công chúng thành viên sẽ sửa lỗi này. Ngoài ra, bạn có thể đặt nội bộ và sử dụng thuộc tính InternalsVisibleToAttribution trên tổ hợp của mình để cho phép tuần tự hóa các thành viên nội bộ
Cur

1
@DanCsharpster Và khi thay đổi thuộc tính Dữ liệu thành thành viên (không có get; set;), tôi nhận được: Một ngoại lệ cơ hội đầu tiên của loại 'System.ArgumentException' xảy ra trong System.ServiceModel.Web.ni.dll Thông tin bổ sung: Đối tượng của loại 'System.Object' không thể được chuyển đổi thành loại 'System.Collections.Generic.Dixi`2 [System.String, System.String]'.
Cœur

0

Đối với bất kỳ ai đang cố gắng chuyển đổi JSON thành từ điển chỉ để lấy một số giá trị từ đó. có một cách đơn giản sử dụngNewtongsoft.JSON

using Newtonsoft.Json.Linq
...

JObject o = JObject.Parse(@"{
  'CPU': 'Intel',
  'Drives': [
    'DVD read/writer',
    '500 gigabyte hard drive'
  ]
}");

string cpu = (string)o["CPU"];
// Intel

string firstDrive = (string)o["Drives"][0];
// DVD read/writer

IList<string> allDrives = o["Drives"].Select(t => (string)t).ToList();
// DVD read/writer
// 500 gigabyte hard drive
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.