ChatGPT解决这个技术问题 Extra ChatGPT

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

我有这样的课程:

class MyDate
{
    int year, month, day;
}

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

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

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

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

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

可以加载 JSON.net here 另一种更快(正如他们所说 - 我自己没有测试过)的解决方案是 ServiceStack.Text 我不建议滚动您自己的 JSON 解析器。它可能会更慢且更容易出错,或者您必须投入大量时间。
是的。 C# 有一个名为 JavaScriptSerializer 的类型
嗯..据我所见,您应该可以使用:msdn.microsoft.com/en-us/library/… 根据 MSDN 页面,它也在 .Net 4.0 中。您应该能够使用 Serialize(Object obj) 方法:msdn.microsoft.com/en-us/library/bb292287.aspx我在这里遗漏了什么吗?顺便提一句。您的链接似乎是一些代码而不是链接
更不用说它不依赖于 System.Web.Xyz 命名空间......

P
Peter Mortensen

既然我们都喜欢单线

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

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

文档:Serializing and Deserializing JSON


Newtonsoft 序列化器比内置的更快,更可定制。强烈推荐使用它。感谢@willsteel的回答
@JosefPfleger 定价适用于 JSON.NET Schema,而不是 JSON.NET 常规序列化程序,即 MIT
我的测试表明 Newtonsoft 比 JavaScriptSerializer 类慢。 (.NET 4.5.2)
如果您阅读 JavaScriptSerializer 的 MSDN 文档,就会发现使用 JSON.net。
@JosefPfleger Newtionsoft JSON.net 已获得 MIT 许可......您可以进行修改并根据需要转售。他们的定价页面是关于商业技术支持和他们拥有的一些模式验证器。
C
Caius Jard

请注意

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

请记住,Microsoft 建议使用 JSON.net 而不是此解决方案。我认为这个答案变得不恰当。看看willsteel的回答。来源:https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx
@DarinDimitrov 您应该考虑添加有关 JSON.net 的提示。 Microsoft 推荐它而不是 JavascriptSerializer:msdn.microsoft.com/en-us/library/… 您还可以向 msdn.microsoft.com/en-us/library/… 添加提示,这是包含框架的方法
here在线工具,用于将您的 classes 转换为 json 格式,希望对某人有所帮助。
为什么微软会推荐第三方解决方案而不是他们自己的解决方案?他们的措辞也很奇怪:“Json.NET 应该使用序列化和反序列化。为启用 AJAX 的应用程序提供序列化和反序列化功能。”
请注意,要引用 System.Web.Extensions,您必须在系统上安装 ASP.NET AJAX 1.0ASP.NET 3.5。请看这个stackoverflow.com/questions/7723489/…
G
Gokulan P H

使用 Json.Net 库,您可以从 Nuget Packet Manager 下载它。

序列化为 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 );

E
Edgar

使用 DataContractJsonSerializer 类:MSDN1MSDN2

我的示例:HERE

JavaScriptSerializer 不同,它还可以安全地从 JSON 字符串反序列化对象。但我个人还是更喜欢Json.NET


那个页面上仍然看不到任何示例,但这里有一些在 MSDNelsewhere ->最后一种使用扩展方法来实现单行。
哦,我错过了第二个 MSDN 链接 :)
它不会序列化普通类。错误报告“考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。如果类型是集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。”
@MichaelFreidgeim没错,您必须在要使用属性序列化的类中标记属性。 DataContractAttribute DataMemberAttribute
@MichaelFreidgeim哪个更好取决于要求。属性允许您配置属性的序列化方式。
t
tdykstra

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

示例代码:

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 序列化程序当前不序列化字段。

文档:

System.Text.Json 概述

如何使用 System.Text.Json


旁注:(1)为了管理 json 序列化,类的属性必须至少具有 getter,(2)JsonSerializer.Serialize(lad) 在一行中打印所有内容;如果您想获得缩进的打印输出,请使用 json options,(3) 我宁愿在类本身中覆盖 ToString(),这样您就不必再写整个 JsonSerializer.Serialize(lad) 句子,只需放在类:public override string ToString() => JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
P
Peter Mortensen

您可以通过使用 Newtonsoft.json 来实现。从 NuGet 安装 Newtonsoft.json。接着:

using Newtonsoft.Json;

var jsonString = JsonConvert.SerializeObject(obj);

M
Majid

呜呜!使用 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 字符串并填充类的字段。


好帖子,这是最新的方法。
我想有人希望在“测试”部分下找到一个单元测试,而没有。顺便说一句,我喜欢 Contact 对象知道如何将自己转换为 JSON 的方法。在这个例子中我不喜欢的是,从 OOP 的角度来看,对象实际上并不是一个对象,而不仅仅是一堆公共方法和属性。
com.blogspot.jeanjmichel.jsontest.main”啊,一个Java程序员陷入了黑暗的一面。欢迎。我们有饼干。
哈哈哈哈哈哈是的@Corey =)
P
Peter Mortensen

如果它们不是很大,那么您可能会将其导出为 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);
}

m
micahhoover

如果您在 ASP.NET MVC Web 控制器中,它很简单:

string ladAsJson = Json(Lad);

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


我收到一个关于无法将 jsonresult 转换为字符串的错误。
它将使用隐式类型进行编译:var ladAsJson = Json(Lad)。
A
Aage

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

using ServiceStack;

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

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


这些都是非常古老的基准。我刚刚测试了 Newtonsoft、ServiceStack 和 JavaScriptSerializer 的所有三个当前版本,目前 Newtonsoft 是最快的。他们都做得很快。
ServiceStack 似乎不是免费的。
@joelnet 现在就是这种情况,但在回答问题时是免费的。但是它对小型网站是免费的,即使它是付费的,我仍在使用它,它是一个极好的框架。
这里有一些基准测试,尽管序列化本身没有:docs.servicestack.net/real-world-performance
@joelnet 现在似乎是免费的。不知道他们什么时候改的。
A
Artur INTECH

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

通过测试:

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

我必须在未连接到 Internet 的 VM 中编写代码,所以这非常有用。
P
Peter Mortensen

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

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

web 下没有默认脚本。 :(
您正在寻找这个:msdn.microsoft.com/en-us/library/…
我尝试过,但没有。脚本我想我应该将其添加为参考。所以非常感谢
M
Mimina

在您的 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);
}

JsonSerializer.Serialize<Lad>(this) 可以简化为 JsonSerializer.Serialize(this)
旁注:(1)为了管理 json 序列化,类的属性必须至少具有 getter,(2)JsonSerializer.Serialize(lad) 在一行中打印所有内容;如果您想获得缩进的打印输出,请使用 json options,(3) 我宁愿像这样覆盖 ToString()public override string ToString() => JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
C
Cinchoo

这是使用 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
  }
}

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


d
dynamiclynk

串行器

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