如何在 .NET 中将 C# 对象转换为 JSON 字符串?

How do I turn a C# object into a JSON string in .NET?

提问人:Hui 提问时间:6/1/2011 最后编辑:John SmithHui 更新时间:10/20/2023 访问量:2091095

问:

我有这样的课程:

class MyDate
{
    int year, month, day;
}

class Lad
{
    string firstName;
    string lastName;
    MyDate dateOfBirth;
}

我想将一个对象转换为JSON字符串,如下所示:Lad

{
    "firstName":"Markoff",
    "lastName":"Chaney",
    "dateOfBirth":
    {
        "year":"1901",
        "month":"4",
        "day":"30"
    }
}

(不带格式)。我找到了这个链接,但它使用了 .NET 4 中没有的命名空间。我也听说过 JSON.NET,但他们的网站目前似乎已经关闭,而且我不热衷于使用外部DLL文件。

除了手动创建 JSON 字符串编写器之外,还有其他选择吗?

C# .NET JSON 序列化

评论

0赞 Filip Ekberg 6/1/2011
泛型/JSON JavaScriptSerializer C# 的可能重复项
1赞 Glenn Ferrie 6/1/2011
是的。C# 有一个名为 JavaScriptSerializer 的类型
3赞 Holger 6/1/2011
嗯。据我所知,您应该能够使用:msdn.microsoft.com/en-us/library/......根据 MSDN 页面,它也在 .Net 4.0 中。您应该能够使用 Serialize(Object obj) 方法: msdn.microsoft.com/en-us/library/bb292287.aspx 我在这里遗漏了什么吗?顺便说一句,你的链接似乎是一个代码,而不是一个链接
4赞 Zebi 6/1/2011
JSON.net 可以在这里加载 另一个更快(正如他们所说 - 我自己没有测试过)的解决方案是 ServiceStack.Text 我不建议滚动您自己的 JSON 解析器。它可能会更慢,更容易出错,或者您必须投入大量时间。

答:

64赞 Edgar 6/1/2011 #1

使用类:MSDN1、MSDN2DataContractJsonSerializer

我的例子:这里

与 .但就我个人而言,我仍然更喜欢 Json.NETJavaScriptSerializer

评论

2赞 Cristian Diaconescu 1/18/2015
仍然没有在该页面上看到任何示例,但这里有一些在 MSDN其他地方 - >最后一个使用扩展方法来实现单行。
0赞 Cristian Diaconescu 1/19/2015
哦,我错过了第二个MSDN链接:)
4赞 Michael Freidgeim 7/14/2016
它不会序列化普通类。错误报告“请考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记要序列化的所有成员。如果类型是集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。
0赞 Edgar 7/15/2016
@MichaelFreidgeim 没错,您必须使用属性来标记要序列化的类中的属性。数据合约属性 数据成员属性
1赞 Edgar 7/15/2016
@MichaelFreidgeim 哪个更好取决于要求。通过这些特性,可以配置属性的序列化方式。
1019赞 Darin Dimitrov 6/1/2011 #2

注意事项

Microsoft 建议您不要使用 JavaScriptSerializer

请参阅文档页面的标题:

对于 .NET Framework 4.7.2 及更高版本,请使用 System.Text.Json 命名空间中的 API 进行序列化和反序列化。对于早期版本的 .NET Framework,请使用 Newtonsoft.Json。


原答案:

您可以使用 JavaScriptSerializer 类(添加对 :System.Web.Extensions

using System.Web.Script.Serialization;
var json = new JavaScriptSerializer().Serialize(obj);

一个完整的例子:

using System;
using System.Web.Script.Serialization;

public class MyDate
{
    public int year;
    public int month;
    public int day;
}

public class Lad
{
    public string firstName;
    public string lastName;
    public MyDate dateOfBirth;
}

class Program
{
    static void Main()
    {
        var obj = new Lad
        {
            firstName = "Markoff",
            lastName = "Chaney",
            dateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };
        var json = new JavaScriptSerializer().Serialize(obj);
        Console.WriteLine(json);
    }
}

评论

121赞 rzelek 2/1/2016
请记住,Microsoft建议使用 JSON.net 而不是此解决方案。我认为这个答案变得不合适。看看willsteel的回答。资料来源:https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
14赞 Mafii 7/6/2016
@DarinDimitrov您应该考虑添加有关 JSON.net 的提示。Microsoft推荐它而不是 JavascriptSerializer:msdn.microsoft.com/en-us/library/...您还可以添加提示 msdn.microsoft.com/en-us/library/...,这是包含框架的方法
2赞 Shaiju T 1/25/2017
这是将你的格式转换为格式的在线工具,希望对某人有所帮助。classesjson
9赞 Protector one 3/17/2017
为什么 Microsoft 会推荐第三方解决方案而不是他们自己的解决方案?他们的措辞也很奇怪:“Json.NET 应该使用序列化和反序列化。为支持 AJAX 的应用程序提供序列化和反序列化功能。
2赞 Sisir 10/15/2018
请注意,您必须在系统上安装或安装。请看这个 stackoverflow.com/questions/7723489/...System.Web.ExtensionsASP.NET AJAX 1.0ASP.NET 3.5
1442赞 mschmoock 10/2/2013 #3

因为我们都喜欢单行本

...这个依赖于 Newtonsoft NuGet 包,该包很受欢迎,并且比默认的序列化程序更好。

Newtonsoft.Json.JsonConvert.SerializeObject(new {foo = "bar"})

文档:序列化和反序列化 JSON

评论

168赞 Andrei 10/2/2013
Newtonsoft 序列化器速度更快,可定制,然后内置。强烈推荐使用它。感谢您的回答@willsteel
9赞 David Cumps 6/4/2015
@JosefPfleger定价是针对 JSON.NET 架构的,而不是 JSON.NET 常规序列化程序(即 MIT)定价的
37赞 dsghi 11/5/2015
如果您阅读了 JavaScriptSerializer 的 MSDN 文档,它直截了当地说使用 JSON.net。
6赞 cb88 8/24/2016
@JosefPfleger Newtionsoft JSON.net 已获得 MIT 许可......您可以进行修改并转售您想要的东西。他们的定价页面是关于商业技术支持的,以及他们拥有的一些模式验证器。
6赞 Jim Aho 5/25/2021
对于阅读本文的每个人来说,请注意这个答案非常非常古老。尽管 Newtonsoft.Json 仍然非常流行,并且可以完成这项工作,但请考虑使用其他答案中提到的新的(内置)System.Text.Json
6赞 James 10/2/2013 #4

我会投票给ServiceStack的JSON序列化器:

using ServiceStack;

string jsonString = new { FirstName = "James" }.ToJson();

它也是可用于 .NET 的最快 JSON 序列化程序:http://www.servicestack.net/benchmarks/

评论

6赞 Michael Logutov 10/25/2013
这些都是非常古老的基准。我刚刚测试了 Newtonsoft、ServiceStack 和 JavaScriptSerializer 的所有三个当前版本,目前 Newtonsoft 是最快的。他们都做得很快。
1赞 joelnet 12/19/2013
ServiceStack 似乎不是免费的。
1赞 James 12/19/2013
@joelnet现在是这样,但在回答问题时是自由的。但是,它对小型网站是免费的,即使它是付费的,我仍然在使用它,它是一个极好的框架。
0赞 JohnLBevan 12/13/2018
这里有一些基准测试,尽管序列化本身没有:docs.servicestack.net/real-world-performance
2赞 Aage 6/22/2020
@joelnet 现在好像是自由的。不知道他们什么时候改的。
25赞 Jean J. Michel 2/5/2014 #5

呜呜!使用 JSON 框架确实更好:)

以下是我使用 Json.NET (http://james.newtonking.com/json) 的示例:

using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using System.IO;

namespace com.blogspot.jeanjmichel.jsontest.model
{
    public class Contact
    {
        private Int64 id;
        private String name;
        List<Address> addresses;

        public Int64 Id
        {
            set { this.id = value; }
            get { return this.id; }
        }

        public String Name
        {
            set { this.name = value; }
            get { return this.name; }
        }

        public List<Address> Addresses
        {
            set { this.addresses = value; }
            get { return this.addresses; }
        }

        public String ToJSONRepresentation()
        {
            StringBuilder sb = new StringBuilder();
            JsonWriter jw = new JsonTextWriter(new StringWriter(sb));

            jw.Formatting = Formatting.Indented;
            jw.WriteStartObject();
            jw.WritePropertyName("id");
            jw.WriteValue(this.Id);
            jw.WritePropertyName("name");
            jw.WriteValue(this.Name);

            jw.WritePropertyName("addresses");
            jw.WriteStartArray();

            int i;
            i = 0;

            for (i = 0; i < addresses.Count; i++)
            {
                jw.WriteStartObject();
                jw.WritePropertyName("id");
                jw.WriteValue(addresses[i].Id);
                jw.WritePropertyName("streetAddress");
                jw.WriteValue(addresses[i].StreetAddress);
                jw.WritePropertyName("complement");
                jw.WriteValue(addresses[i].Complement);
                jw.WritePropertyName("city");
                jw.WriteValue(addresses[i].City);
                jw.WritePropertyName("province");
                jw.WriteValue(addresses[i].Province);
                jw.WritePropertyName("country");
                jw.WriteValue(addresses[i].Country);
                jw.WritePropertyName("postalCode");
                jw.WriteValue(addresses[i].PostalCode);
                jw.WriteEndObject();
            }

            jw.WriteEndArray();

            jw.WriteEndObject();

            return sb.ToString();
        }

        public Contact()
        {
        }

        public Contact(Int64 id, String personName, List<Address> addresses)
        {
            this.id = id;
            this.name = personName;
            this.addresses = addresses;
        }

        public Contact(String JSONRepresentation)
        {
            //To do
        }
    }
}

测试:

using System;
using System.Collections.Generic;
using com.blogspot.jeanjmichel.jsontest.model;

namespace com.blogspot.jeanjmichel.jsontest.main
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<Address> addresses = new List<Address>();
            addresses.Add(new Address(1, "Rua Dr. Fernandes Coelho, 85", "15º andar", "São Paulo", "São Paulo", "Brazil", "05423040"));
            addresses.Add(new Address(2, "Avenida Senador Teotônio Vilela, 241", null, "São Paulo", "São Paulo", "Brazil", null));

            Contact contact = new Contact(1, "Ayrton Senna", addresses);

            Console.WriteLine(contact.ToJSONRepresentation());
            Console.ReadKey();
        }
    }
}

结果:

{
  "id": 1,
  "name": "Ayrton Senna",
  "addresses": [
    {
      "id": 1,
      "streetAddress": "Rua Dr. Fernandes Coelho, 85",
      "complement": "15º andar",
      "city": "São Paulo",
      "province": "São Paulo",
      "country": "Brazil",
      "postalCode": "05423040"
    },
    {
      "id": 2,
      "streetAddress": "Avenida Senador Teotônio Vilela, 241",
      "complement": null,
      "city": "São Paulo",
      "province": "São Paulo",
      "country": "Brazil",
      "postalCode": null
    }
  ]
}

现在,我将实现构造函数方法,该方法将接收 JSON 字符串并填充类的字段。

评论

1赞 MatthewD 5/30/2016
好帖子,这是最新的方法。
1赞 Artur INTECH 3/14/2021
我猜人们希望在“测试”部分下找到一个单元测试,而没有。顺便说一句,我喜欢对象知道如何将自身转换为 JSON 的方法。在这个例子中,我不喜欢的是,从OOP的角度来看,对象实际上并不是一个对象,而不仅仅是一堆公共方法和属性。Contact
0赞 Corey 6/8/2021
"com.blogspot.jeanjmichel.jsontest.main“啊,一个Java程序员陷入了黑暗的一面。欢迎。我们有cookies。
0赞 Jean J. Michel 6/23/2021
哈哈哈哈哈是的@Corey=)
2赞 MarzSocks 6/26/2014 #6

就这么简单(它也适用于动态对象(类型对象)):

string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MYOBJECT);

评论

0赞 M at 7/11/2016
Web 下没有默认脚本。:(
0赞 MarzSocks 7/12/2016
您正在寻找这个:msdn.microsoft.com/en-us/library/...
0赞 M at 7/12/2016
我试过了,但没有。脚本我想我应该添加它作为参考。非常感谢
0赞 dynamiclynk 2/4/2016 #7

序列化程序

 public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
        var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite, new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
        });
        using (var writer = new StreamWriter(filePath, append))
        {
            writer.Write(contentsToWriteToFile);
        }
}

对象

namespace MyConfig
{
    public class AppConfigurationSettings
    {
        public AppConfigurationSettings()
        {
            /* initialize the object if you want to output a new document
             * for use as a template or default settings possibly when 
             * an app is started.
             */
            if (AppSettings == null) { AppSettings=new AppSettings();}
        }

        public AppSettings AppSettings { get; set; }
    }

    public class AppSettings
    {
        public bool DebugMode { get; set; } = false;
    }
}

实现

var jsonObject = new AppConfigurationSettings();
WriteToJsonFile<AppConfigurationSettings>(file.FullName, jsonObject);

输出

{
  "AppSettings": {
    "DebugMode": false
  }
}
8赞 micahhoover 9/16/2016 #8

如果你在 ASP.NET MVC Web 控制器中,它就像这样简单:

string ladAsJson = Json(Lad);

不敢相信没有人提到过这一点。

评论

1赞 csga5000 9/23/2016
我收到一个关于无法将jsonresult转换为字符串的错误。
0赞 ewomack 11/8/2016
它将使用隐式类型进行编译:var ladAsJson = Json(Lad)。
135赞 Gokulan P H 6/21/2017 #9

使用 Json.Net 库,可以从 Nuget 数据包管理器下载它。

序列化为 json 字符串:

 var obj = new Lad
        {
            firstName = "Markoff",
            lastName = "Chaney",
            dateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };

var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(obj);

反序列化为对象:

var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Lad>(jsonString );
10赞 user8426627 1/29/2018 #10

如果它们不是很大,那么您的情况可能是将其导出为 JSON。

此外,这使得它在所有平台之间具有可移植性。

using Newtonsoft.Json;

[TestMethod]
public void ExportJson()
{
    double[,] b = new double[,]
        {
            { 110,  120,  130,  140, 150 },
            {1110, 1120, 1130, 1140, 1150},
            {1000,    1,   5,     9, 1000},
            {1110,    2,   6,    10, 1110},
            {1220,    3,   7,    11, 1220},
            {1330,    4,   8,    12, 1330}
        };

    string jsonStr = JsonConvert.SerializeObject(b);

    Console.WriteLine(jsonStr);

    string path = "X:\\Programming\\workspaceEclipse\\PyTutorials\\src\\tensorflow_tutorials\\export.txt";

    File.WriteAllText(path, jsonStr);
}
37赞 Waleed Naveed 8/2/2019 #11

可以使用 Newtonsoft.json 实现此目的。从 NuGet 安装 Newtonsoft.json。然后:

using Newtonsoft.Json;

var jsonString = JsonConvert.SerializeObject(obj);
72赞 tdykstra 10/9/2019 #12

命名空间中提供了新的 JSON 序列化程序。它包含在 .NET Core 3.0 共享框架中,并且位于面向 .NET Standard、.NET Framework 或 .NET Core 2.x 的项目的 NuGet 包中。System.Text.Json

示例代码:

using System;
using System.Text.Json;

public class MyDate
{
    public int year { get; set; }
    public int month { get; set; }
    public int day { get; set; }
}

public class Lad
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public MyDate DateOfBirth { get; set; }
}

class Program
{
    static void Main()
    {
        var lad = new Lad
        {
            FirstName = "Markoff",
            LastName = "Chaney",
            DateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };
        var json = JsonSerializer.Serialize(lad);
        Console.WriteLine(json);
    }
}

在此示例中,要序列化的类具有属性而不是字段;序列化程序当前不序列化字段。System.Text.Json

文档:

评论

0赞 Paul Efford 12/23/2021
旁注:(1)为了管理json序列化,类的属性必须至少具有getter,(2)在一行中打印所有内容;如果你想得到一个缩进的打印输出,使用json,(3)我宁愿在类本身中覆盖,这样你就再也不用写了整个句子了,只要把这个放在类里面就行了:JsonSerializer.Serialize(lad)optionsToString()JsonSerializer.Serialize(lad)public override string ToString() => JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
7赞 Mimina 2/14/2021 #13

在 Lad 模型类中,向 ToString() 方法添加一个重写,该方法返回 Lad 对象的 JSON 字符串版本。
注意:您需要导入 System.Text.Json
;

using System.Text.Json;

class MyDate
{
    int year, month, day;
}

class Lad
{
    public string firstName { get; set; };
    public string lastName { get; set; };
    public MyDate dateOfBirth { get; set; };
    public override string ToString() => JsonSerializer.Serialize<Lad>(this);
}

评论

1赞 malat 10/21/2021
JsonSerializer.Serialize<Lad>(this)可以简化为JsonSerializer.Serialize(this)
2赞 Paul Efford 12/23/2021
旁注:(1)为了管理json序列化,类的属性必须至少具有getter,(2)在一行中打印所有内容;如果你想得到一个缩进的打印输出,请使用json,(3)我宁愿像这样覆盖:JsonSerializer.Serialize(lad)optionsToString()public override string ToString() => JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
7赞 Artur INTECH 3/15/2021 #14

2023 年 10 月更新:

使用内置 (.NET Core 3.0+) 的另一种解决方案,其中对象是自给自足的,不会公开所有可能的字段:System.Text.Json

通过测试(使用 NUnit):

using NUnit.Framework;

namespace Intech.UnitTests
{
    public class UserTests
    {
        [Test]
        public void ConvertsItselfToJson()
        {
            var userName = "John";
            var user = new User(userName);

            var actual = user.ToJson();

            Assert.AreEqual($"{{\"Name\":\"{userName}\"}}", actual);
        }
    }
}

实现:

using System.Text.Json;
using System.Collections.Generic;

namespace Intech
{
    public class User
    {
        private readonly string name;

        public User(string name)
        {
            this.name = name;
        }

        public string ToJson()
        {
            var params = new Dictionary<string, string>{{"Name", name}};
            return JsonSerializer.Serialize(params);
        }
    }
}

评论

0赞 TomDestry 4/15/2021
我不得不在未连接到互联网的 VM 中编写代码,因此这非常有用。
1赞 Cinchoo 3/26/2021 #15

这是使用 Cinchoo ETL 的另一种解决方案 - 一个开源库

public class MyDate
{
    public int year { get; set; }
    public int month { get; set; }
    public int day { get; set; }
}

public class Lad
{
    public string firstName { get; set; }
    public string lastName { get; set; }
    public MyDate dateOfBirth { get; set; }
}

static void ToJsonString()
{
    var obj = new Lad
    {
        firstName = "Tom",
        lastName = "Smith",
        dateOfBirth = new MyDate
        {
            year = 1901,
            month = 4,
            day = 30
        }
    };
    var json = ChoJSONWriter.Serialize<Lad>(obj);

    Console.WriteLine(json);
}

输出:

{
  "firstName": "Tom",
  "lastName": "Smith",
  "dateOfBirth": {
    "year": 1901,
    "month": 4,
    "day": 30
  }
}

免责声明:我是这个库的作者。