Tuần tự hóa một danh sách thành JSON


182

Tôi có một mô hình đối tượng trông như thế này:

public MyObjectInJson
{
   public long ObjectID {get;set;}
   public string ObjectInJson {get;set;}
}

Thuộc tính ObjectInJsonlà một phiên bản đã được tuần tự hóa một đối tượng có chứa các danh sách lồng nhau. Hiện tại, tôi đang tuần tự hóa danh sách MyObjectInJsonthủ công như thế này:

StringBuilder TheListBuilder = new StringBuilder();

TheListBuilder.Append("[");
int TheCounter = 0;

foreach (MyObjectInJson TheObject in TheList)
{
  TheCounter++;
  TheListBuilder.Append(TheObject.ObjectInJson);

  if (TheCounter != TheList.Count())
  {
    TheListBuilder.Append(",");
  }
}
TheListBuilder.Append("]");

return TheListBuilder.ToString();

Tôi tự hỏi nếu tôi có thể thay thế loại mã nguy hiểm này JavascriptSerializervà nhận được kết quả tương tự. Làm thế nào tôi sẽ làm điều này?

Cảm ơn.


Lưu ý rằng trong một dự án WPF, bạn cần thêm một tham chiếu System.Web.Extensionsđể sử dụng System.Web.Script.Serialization: stackoverflow.com/a/18746092/1599699 stackoverflow.com/a/19299695/1599699
Andrew

Câu trả lời:


338

Nếu sử dụng .Net Core 3.0 trở lên;

Mặc định sử dụng System.Text.Jsonthực thi trình phân tích cú pháp tích hợp.

ví dụ

using System.Text.Json;

var json = JsonSerializer.Serialize(aList);

cách khác, các tùy chọn khác, ít chính thống hơn có sẵn như trình phân tích cú pháp Utf8JsonJil : Chúng có thể cung cấp hiệu suất vượt trội , nếu bạn thực sự cần nó, nhưng bạn sẽ cần phải cài đặt các gói tương ứng của chúng.

Nếu bị kẹt khi sử dụng .Net Core 2.2 trở về trước;

Mặc định sử dụng Newtonsoft JSON.Net làm Trình phân tích cú pháp JSON lựa chọn đầu tiên của bạn.

ví dụ

using Newtonsoft.Json;

var json = JsonConvert.SerializeObject(aList);

bạn có thể cần phải cài đặt gói đầu tiên.

PM> Install-Package Newtonsoft.Json

Để biết thêm chi tiết, xem và nêu lên câu trả lời là nguồn gốc của thông tin này .

Chỉ để tham khảo, đây là câu trả lời ban đầu, nhiều năm trước;

// you need to reference System.Web.Extensions

using System.Web.Script.Serialization;

var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(aList);

1
ah ok, nó cũng tuần tự hóa danh sách các đối tượng và không chỉ các đối tượng. Cảm ơn.
Frenchie

không thích các mối quan hệ theo chu kỳ nhưng đó không phải là vấn đề ở đây
Jodrell

13
Lưu ý rằng không gian tên này được giấu khéo léo trong System.Web.Extensions. Khi bạn thêm nó làm tài liệu tham khảo, giải pháp hoạt động tuyệt vời!
tám bit

1
Tôi thấy câu trả lời được chỉnh sửa của bạn và thực sự muốn tôi có một ví dụ cập nhật.
Dylan Brams

1
@ IamNumber5 đã được cung cấp trong câu trả lời khác. Tôi mở rộng câu trả lời của tôi nào.
Jodrell

111

Bạn cũng có thể sử dụng Json.NET. Chỉ cần tải xuống tại http://james.newtonking.com/pages/json-net.aspx , giải nén tệp nén và thêm nó làm tài liệu tham khảo.

Sau đó, chỉ cần tuần tự hóa danh sách (hoặc bất kỳ đối tượng nào bạn muốn) với các mục sau:

using Newtonsoft.Json;

string json = JsonConvert.SerializeObject(listTop10);

Cập nhật: bạn cũng có thể thêm nó vào dự án của mình thông qua Trình quản lý gói NuGet (Công cụ -> Trình quản lý gói NuGet -> Bảng điều khiển quản lý gói):

PM> Install-Package Newtonsoft.Json

Tài liệu: Bộ sưu tập nối tiếp


12

Có hai cách phổ biến để thực hiện điều đó với các trình tuần tự hóa JSON tích hợp:

  1. JavaScriptSerializer

    var serializer = new JavaScriptSerializer();
    return serializer.Serialize(TheList);
  2. DataContractJsonSerializer

    var serializer = new DataContractJsonSerializer(TheList.GetType());
    using (var stream = new MemoryStream())
    {
        serializer.WriteObject(stream, TheList);
        using (var sr = new StreamReader(stream))
        {
            return sr.ReadToEnd();
        }
    }

    Lưu ý rằng tùy chọn này yêu cầu định nghĩa về hợp đồng dữ liệu cho lớp của bạn:

    [DataContract]
    public class MyObjectInJson
    {
       [DataMember]
       public long ObjectID {get;set;}
       [DataMember]
       public string ObjectInJson {get;set;}
    }

5
public static string JSONSerialize<T>(T obj)
        {
            string retVal = String.Empty;
            using (MemoryStream ms = new MemoryStream())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
                serializer.WriteObject(ms, obj);
                var byteArray = ms.ToArray();
                retVal = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
            }
            return retVal;
        }

4

.NET đã hỗ trợ tuần tự hóa Json cơ bản thông qua không gian tên System.R nb.Serialization.Json và lớp DataContractJsonSerializer kể từ phiên bản 3.5. Như tên của nó, DataContractJsonSerializer sẽ tính đến mọi chú thích dữ liệu bạn thêm vào các đối tượng của mình để tạo đầu ra Json cuối cùng.

Điều đó có thể hữu ích nếu bạn đã có các lớp dữ liệu chú thích mà bạn muốn tuần tự hóa Json thành một luồng, như được mô tả trong Cách thực hiện: Nối tiếp và giải nén dữ liệu JSON . Có những hạn chế nhưng nó đủ tốt và đủ nhanh nếu bạn có nhu cầu cơ bản và không muốn thêm Thư viện Yet Another vào dự án của mình.

Đoạn mã sau đây nối tiếp một danh sách vào luồng đầu ra của bàn điều khiển. Như bạn thấy, nó dài hơn một chút so với Json.NET và không an toàn kiểu (tức là không có khái quát)

        var list = new List<string> {"a", "b", "c", "d"};

        using(var output = Console.OpenStandardOutput())                
        {                
            var writer = new DataContractJsonSerializer(typeof (List<string>));
            writer.WriteObject(output,list);
        }

Mặt khác, Json.NET cung cấp khả năng kiểm soát tốt hơn nhiều so với cách bạn tạo Json. Điều này sẽ rất hữu ích khi bạn phải ánh xạ các tên thân thiện với javascript sang các lớp .NET, định dạng ngày thành json, v.v.

Một tùy chọn khác là ServiceStack.Text , một phần của ngăn xếp ServicStack ..., cung cấp một bộ tuần tự hóa rất nhanh cho Json, JSV và CSV.


0

dựa trên câu trả lời từ một bài đăng khác .. Tôi đã đưa ra một cách chung hơn để xây dựng một danh sách, sử dụng truy xuất động với Json.NET phiên bản 12.x

using Newtonsoft.Json;

static class JsonObj
{
    /// <summary>
    /// Deserializes a json file into an object list
    /// Author: Joseph Poirier 2/26/2019
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public static List<T> DeSerializeObject<T>(string fileName)
    {
        List<T> objectOut = new List<T>();

        if (string.IsNullOrEmpty(fileName)) { return objectOut; }

        try
        {
            // reading in full file as text
            string ss = File.ReadAllText(fileName);

            // went with <dynamic> over <T> or <List<T>> to avoid error..
            //  unexpected character at line 1 column 2
            var output = JsonConvert.DeserializeObject<dynamic>(ss);

            foreach (var Record in output)
            {
                foreach (T data in Record)
                {
                    objectOut.Add(data);
                }
            }
        }
        catch (Exception ex)
        {
            //Log exception here
            Console.Write(ex.Message);
        }

        return objectOut;
    }
}

gọi để xử lý

{
        string fname = "../../Names.json"; // <- your json file path

        // for alternate types replace string with custom class below
        List<string> jsonFile = JsonObj.DeSerializeObject<string>(fname);
}

hoặc cuộc gọi này để xử lý

{
        string fname = "../../Names.json"; // <- your json file path

        // for alternate types replace string with custom class below
        List<string> jsonFile = new List<string>();
        jsonFile.AddRange(JsonObj.DeSerializeObject<string>(fname));
}
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.