【问题标题】:How do I turn a C# object into a JSON string in .NET?如何在 .NET 中将 C# 对象转换为 JSON 字符串?
【发布时间】:2011-09-06 06:56:46
【问题描述】:

我有这样的课程:

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 命名空间...

标签: c# .net json serialization


【解决方案1】:

使用DataContractJsonSerializer 类:MSDN1MSDN2

我的例子:HERE

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

【讨论】:

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

【讨论】:

【解决方案3】:

因为我们都喜欢单线

...这个依赖于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 许可……您可以根据需要进行修改并转售。他们的定价页面是关于商业技术支持和他们拥有的一些架构验证器。
【解决方案4】:

我会投票给 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 现在好像免费了。不知道他们什么时候改的。
【解决方案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 字符串并填充类字段的构造方法。

【讨论】:

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

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

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

【讨论】:

【解决方案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】:

    如果你在一个 ASP.NET MVC web 控制器中,它很简单:

    string ladAsJson = Json(Lad);
    

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

    【讨论】:

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

    使用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 );
    

    【讨论】:

      【解决方案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);
      }
      

      【讨论】:

        【解决方案11】:

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

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

        【讨论】:

          【解决方案12】:

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

          文档:

          【讨论】:

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

          在您的 Lad 模型类中,为返回 Lad 对象的 JSON 字符串版本的 ToString() 方法添加一个覆盖。
          注意:您需要导入 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&lt;Lad&gt;(this)可以简化为JsonSerializer.Serialize(this)
          • 旁注:(1) 为了管理 json 序列化,类的属性必须至少有 getter,(2) JsonSerializer.Serialize(lad) 打印在一行中;如果您想获得缩进的打印输出,请使用 json options,(3) 我宁愿像这样覆盖 ToString()public override string ToString() =&gt; JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
          【解决方案14】:

          另一个使用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);
                  }
              }
          }
          

          【讨论】:

          • 我不得不在未连接到互联网的虚拟机中编写代码,所以这非常有用。
          【解决方案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
            }
          }
          

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

          【讨论】:

            猜你喜欢
            • 2016-10-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-07-12
            相关资源
            最近更新 更多