将列表序列化为 JSON

本文关键字:JSON 序列化 列表 | 更新日期: 2023-09-27 18:22:18

我有一个对象模型,如下所示:

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替换这种危险的代码并获得相同的结果。我该怎么做?

将列表序列化为 JSON

如果使用.

Net Core 3.0或更高版本;

默认使用内置System.Text.Json解析器实现。

例如

using System.Text.Json;
var json = JsonSerializer.Serialize(aList);

或者,其他不太主流的选项也可用,如 Utf8Json 解析器和 Jil:如果您确实需要它,这些可能会提供卓越的性能,但是,您需要安装它们各自的软件包。

如果卡在使用 .Net Core 2.2 或更早版本;

默认使用 Newtonsoft JSON.Net 作为首选 JSON 解析器。

例如

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);
您也可以

使用 Json.NET。只需在 http://james.newtonking.com/pages/json-net.aspx 下载它,提取压缩文件并将其添加为参考。

然后只需使用以下方法序列化列表(或所需的任何对象(:

using Newtonsoft.Json;
string json = JsonConvert.SerializeObject(listTop10);

更新:还可以通过 NuGet 包管理器(工具 --> NuGet 包管理器 --> 包管理器控制台(将其添加到项目中:

PM> Install-Package Newtonsoft.Json

文档:序列化集合

使用内置 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;}
    }
    
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;
        }
.

NET 从 3.5 版开始就已经通过 System.Runtime.Serialization.Json 命名空间和 DataContractJsonSerializer 类支持基本的 Json 序列化。顾名思义,DataContractJsonSerializer 会考虑您添加到对象中的任何数据注释,以创建最终的 Json 输出。

如果已有要将 Json 序列化为流的批注数据类,这将非常方便,如如何:序列化和反序列化 JSON 数据中所述。有限制,但如果您有基本需求并且不想将另一个库添加到您的项目中,那么它足够好和足够快。

下面的代码将列表序列化为控制台输出流。如您所见,它比 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 的方式。当您必须将javascript友好的名称名称映射到.NET类,将日期格式化为json等时,这将非常方便。

另一个选择是ServiceStack.Text,它是ServicStack的一部分。stack,它为 Json、JSV 和 CSV 提供了一组非常快速的序列化程序。

建立在另一个帖子的答案之上。我想出了一种更通用的方法来构建列表,利用 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));
}

如果在 asp.Net Core API 操作的上下文中执行此操作,则会隐式完成对 JSON 的转换。

[HttpGet]
public ActionResult Get()
{
    return Ok(TheList);
}
using System;
  using System.Text.Json;   
  using System.Collections.Generic;
    public class Program
    {
        public static void Main()
        {
            
            List<ErrorDetail>  aList = new List<ErrorDetail>();
            ErrorDetail a = new  ErrorDetail{ ColumnName="aaa", ErrorText="abbbb"};
            ErrorDetail c = new  ErrorDetail{ ColumnName="ccc", ErrorText="cccc"};
            ErrorDetail b = new  ErrorDetail{ ColumnName="ccc", ErrorText="cccc"};
            aList.Add(a);
            aList.Add(b);
            aList.Add(c);
            
            var json = JsonSerializer.Serialize(aList);
            
            Console.WriteLine(json);
        }
        
        public class ErrorDetail
        {
           
            public string ColumnName { get; set; }
    
           
            public string ErrorText { get; set; }
    
    
    
    
        }
    }

我在这里尝试了其他答案来序列化 POST 请求的参数,但我的后端不喜欢我发送数组的字符串版本的事实。我不想总是检查参数的类型是否是字符串并将其转换为数组。

我正在使用 Json.NET(现在内置于 C# 中(,我将我的 List 转换为数组,让转换器处理其余部分。

public class MyObjectInJson 
{
    public long ID;
    public OtherObject[] array;
}

您可以使用 list.ToArray(); 将列表转换为数组

最后使用 JsonConvert ,可以将整个对象变成一个字符串:

string jsonString = JsonConvert.SerializeObject(objectInJson);

希望这对其他人有所帮助。