การจัดลำดับรายการเป็น JSON


182

ฉันมีโมเดลวัตถุที่มีลักษณะเช่นนี้:

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

คุณสมบัติObjectInJsonนี้เป็นวัตถุที่มีรายการซ้อนอยู่ ในขณะนี้ฉันกำลังเรียงลำดับรายการMyObjectInJsonด้วยตนเองดังนี้:

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

ฉันสงสัยว่าฉันสามารถแทนที่รหัสอันตรายประเภทนี้ด้วยJavascriptSerializerและได้ผลลัพธ์เดียวกันหรือไม่ ฉันจะทำสิ่งนี้ได้อย่างไร

ขอบคุณ


โปรดทราบว่าในโครงการ WPF คุณต้องเพิ่มการอ้างอิงSystem.Web.Extensionsเพื่อใช้System.Web.Script.Serialization: stackoverflow.com/a/18746092/1599699 stackoverflow.com/a/19299695/1599699
Andrew

คำตอบ:


338

หากใช้. Net Core 3.0 หรือใหม่กว่า;

เริ่มต้นที่จะใช้การSystem.Text.Jsonดำเนินการ parser ในตัว

เช่น

using System.Text.Json;

var json = JsonSerializer.Serialize(aList);

อีกทางเลือกหนึ่งตัวเลือกที่สำคัญน้อยกว่ามีให้เลือกเช่นUtf8Json parser และJil : สิ่งเหล่านี้อาจมอบประสิทธิภาพที่เหนือกว่าหากคุณต้องการจริงๆ แต่คุณจะต้องติดตั้งแพ็คเกจที่เกี่ยวข้อง

หากใช้งาน. Net Core 2.2 หรือเก่ากว่า

เริ่มต้นที่จะใช้ Newtonsoft JSON.Net เป็นตัวเลือกแรกของคุณ JSON Parser

เช่น

using Newtonsoft.Json;

var json = JsonConvert.SerializeObject(aList);

คุณอาจต้องติดตั้งแพคเกจก่อน

PM> Install-Package Newtonsoft.Json

สำหรับรายละเอียดเพิ่มเติมโปรดดูและโหวตคำตอบที่เป็นแหล่งข้อมูลนี้

สำหรับการอ้างอิงเท่านั้นนี่คือคำตอบเดิมเมื่อหลายปีก่อน

// you need to reference System.Web.Extensions

using System.Web.Script.Serialization;

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

1
อาตกลงมันเป็นอนุกรมรายการของวัตถุและไม่ใช่แค่วัตถุเอง ขอบคุณ
Frenchie

ไม่ชอบความสัมพันธ์ที่เป็นวัฏจักร แต่นั่นไม่ใช่ปัญหาที่นี่
Jodrell

13
โปรดทราบว่าเนมสเปซนี้ซ่อนเร้นอย่างเด็ดขาดใน System.Web.Extensions เมื่อคุณเพิ่มนั่นเป็นข้อมูลอ้างอิงโซลูชันทำงานได้อย่างยอดเยี่ยม!
Eight-Bit Guru

1
ฉันเห็นคำตอบที่คุณแก้ไขและหวังว่าฉันจะได้รับตัวอย่างที่อัปเดตแล้ว
Dylan Brams

1
@ IamNumber5 ระบุไว้แล้วในคำตอบอื่น ๆ ฉันขยายคำตอบของฉันต่อไป
Jodrell

111

คุณยังสามารถใช้ Json.NET เพียงดาวน์โหลดได้ที่http://james.newtonking.com/pages/json-net.aspxแยกไฟล์ที่บีบอัดและเพิ่มเป็นข้อมูลอ้างอิง

จากนั้นเพียงเรียงลำดับรายการ (หรือสิ่งที่คุณต้องการ) ด้วยสิ่งต่อไปนี้:

using Newtonsoft.Json;

string json = JsonConvert.SerializeObject(listTop10);

อัปเดต: คุณยังสามารถเพิ่มลงในโครงการของคุณผ่านทาง NuGet Package Manager (เครื่องมือ -> NuGet Package Manager -> คอนโซลตัวจัดการแพคเกจ):

PM> Install-Package Newtonsoft.Json

เอกสารประกอบ: การทำให้เป็นอันดับคอลเลกชัน


12

มีสองวิธีทั่วไปในการทำเช่นนั้นด้วย serializers JSON ในตัว:

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

    โปรดทราบว่าตัวเลือกนี้ต้องการคำจำกัดความของสัญญาข้อมูลสำหรับคลาสของคุณ:

    [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 รองรับการทำอนุกรม Json พื้นฐานผ่านSystem.Runtime.Serialization.Json namespaceและคลาสDataContractJsonSerializerตั้งแต่รุ่น 3.5 ตามที่มีความหมายชื่อ DataContractJsonSerializer จะพิจารณาคำอธิบายประกอบข้อมูลใด ๆ ที่คุณเพิ่มลงในวัตถุของคุณเพื่อสร้างเอาต์พุต Json สุดท้าย

ที่สามารถเป็นประโยชน์ถ้าคุณได้เรียนข้อเขียนข้อมูลที่คุณต้องการที่จะเป็นอันดับ JSON เพื่อสตรีมที่อธิบายไว้ในวิธีการ: Serialize และ deserialize JSON ข้อมูล มีข้อ จำกัด แต่ก็ดีพอและเร็วพอถ้าคุณมีความต้องการพื้นฐานและไม่ต้องการเพิ่ม Yet Library อีกอันในโครงการของคุณ

รหัสต่อไปนี้เป็นอนุกรมรายการไปยังกระแสออกคอนโซล ในขณะที่คุณเห็นมันเป็นบิตเพิ่มเติมอย่างละเอียดกว่า Json.NET และไม่พิมพ์ปลอดภัย (คือไม่มียาชื่อสามัญ)

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

ในทางกลับกันJson.NETให้การควบคุมวิธีสร้าง Json ได้ดีขึ้นมาก สิ่งนี้จะมีประโยชน์มากเมื่อคุณต้องแม็พชื่อที่เป็นมิตรกับจาวาสคริปต์กับคลาส. NET, วันที่จัดรูปแบบเป็น json เป็นต้น

อีกตัวเลือกหนึ่งคือ ServiceStack.Textซึ่งเป็นส่วนหนึ่งของสแต็คServicStack ... ซึ่งมีชุดของ serializers ที่รวดเร็วมากสำหรับ Json, JSV และ CSV


0

การสร้างคำตอบจากการโพสต์อื่น .. ฉันคิดวิธีทั่วไปในการสร้างรายการโดยใช้การดึงแบบไดนามิกด้วย Json.NET เวอร์ชั่น 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;
    }
}

เรียกร้องให้ดำเนินการ

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

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

หรือการเรียกนี้เพื่อดำเนินการ

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