如何使用 C# 解析 JSON?
Posted
技术标签:
【中文标题】如何使用 C# 解析 JSON?【英文标题】:How can I parse JSON with C#? 【发布时间】:2020-09-14 16:16:16 【问题描述】:我有以下代码:
var user = (Dictionary<string, object>)serializer.DeserializeObject(responsecontent);
responsecontent
中的输入是 JSON,但未正确解析为对象。我应该如何正确反序列化它?
【问题讨论】:
嘿你可能想试试这个链接techblog.procurios.nl/k/n618/news/view/14605/14863/…System.Web.Helpers
中有Json
,System.ServiceModel.Web
中有JsonQueryStringConverter
,System.Web.Script.Serialization
中有javascriptSerializer
,System.Runtime.Serialization.Json
中有DataContractJsonSerializer
,哎呀 MS 甚至决定第三方Json.NET
在其 ASP.NET Web API 中。如果您认为这还不够,MS 正在提出System.Json
,但目前不适合消费。走微软的路……我选择了最好看的命名空间。
@fusi 其余的都在单独的程序集中。谷歌命名空间/类名,你会在 msdn 文档中找到它们所在的程序集。只需添加对该程序集的引用即可。
刚刚完成,Windows.Data.Json
中还有JsonValue
,仅适用于 Windows 8 及更高版本。我喜欢这个。 MS正在执行任务:)
NewtonSoft 在他们的网站上有一个比较页面(可能有偏见,但仍然很有趣):newtonsoft.com/json/help/html/jsonnetvsdotnetserializers.htm。我特别喜欢无意义的字典序列化行:)
【参考方案1】:
我假设您没有使用Json.NET(Newtonsoft.Json NuGet 包)。如果是这种情况,那么您应该尝试一下。
它具有以下特点:
-
LINQ to JSON
JsonSerializer 用于快速将 .NET 对象转换为 JSON 并再次转换回来
Json.NET 可以选择生成格式良好、缩进的 JSON 用于调试或显示
JsonIgnore
和 JsonProperty
等属性可以添加到类中以自定义类的序列化方式
能够将 JSON 与 XML 相互转换
支持多种平台:.NET、Silverlight 和 Compact Framework
看看下面的example。在此示例中,JsonConvert
类用于将对象与 JSON 进行转换。为此,它有两个静态方法。他们是SerializeObject(Object obj)
和DeserializeObject<T>(String json)
:
using Newtonsoft.Json;
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] "Small", "Medium", "Large" ;
string json = JsonConvert.SerializeObject(product);
//
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
【讨论】:
我可以反序列化为var
类型变量,以防我不知道我的目标的完整结构吗?具体来说,我正在使用 Rally 用户故事,我想将它们转换为对象。
@PedroDusso 你可以,这里是完整的doc
@PeterWone:不,JSON.parse('"Expiry": "2008-12-28T00:00:00"').Expiry
返回 字符串 "2008-12-28T00:00:00"
,而不是日期。它可以通过new Date(str)
变成Date
,但JSON.parse
对日期一无所知。你必须传入一个 reviver 来检查每个字符串值是否符合一个模式。
@T.J.Crowder - 我的错。刚刚检查了一下,不仅你是对的,而且比这更糟糕(他死了,吉姆!)具有微妙的不对称不兼容性:JSON.stringify 产生秒到小数点后 2 位 "2015-09-28T01:08:03.704Z" 这令人困惑Date.parse 由 new Date(string) 隐式调用。编写修复程序并重载内置日期解析并不难,但让所有人都使用 Moment.js
由于 3.703 秒与 3s 和 703ms 相同,并且分隔符是小数点,所以我告诉你这是秒到小数点后三位。【参考方案2】:
这里已经回答了 - Deserialize JSON into C# dynamic object?
使用 Json.NET 非常简单:
dynamic stuff = JsonConvert.DeserializeObject(" 'Name': 'Jon Smith', 'Address': 'City': 'New York', 'State': 'NY' , 'Age': 42 ");
string name = stuff.Name;
string address = stuff.Address.City;
或者使用 Newtonsoft.Json.Linq :
dynamic stuff = JObject.Parse(" 'Name': 'Jon Smith', 'Address': 'City': 'New York', 'State': 'NY' , 'Age': 42 ");
string name = stuff.Name;
string address = stuff.Address.City;
【讨论】:
@MaxHodges,你是对的。我只是使用内联“魔术字符串”来演示如何解析 JSON 字符串值。不希望它看起来很复杂,因为转义双引号。在实际代码中,我们通常会从某处获取 JSON 字符串作为变量或作为参数传递。 如果没有 .net 4,您就没有“动态”关键字。您可以使用 'var stuff' 进行声明,而不是 'stuff.Name' 和 'stuff.Address.City' 你分别有 'stuff["Name"]' 和 'stuff["Address"]["City"]' . @Fil 这给你一个object
类型的值,你不能在object
上使用索引。
@Alex 我很确定 Newtonsoft.Json 变体返回一个 JObject。另外,不要使用 Json.NET,即使 VS 现在也使用 Newtonsoft.Json。现在甚至可以在 VSIX 中使用而无需将其添加到包中【参考方案3】:
以下是一些不使用第三方库的选项:
// For that you will need to add reference to System.Runtime.Serialization
var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(@" ""Name"": ""Jon Smith"", ""Address"": ""City"": ""New York"", ""State"": ""NY"" , ""Age"": 42 "), new System.Xml.XmlDictionaryReaderQuotas());
// For that you will need to add reference to System.Xml and System.Xml.Linq
var root = XElement.Load(jsonReader);
Console.WriteLine(root.XPathSelectElement("//Name").Value);
Console.WriteLine(root.XPathSelectElement("//Address/State").Value);
// For that you will need to add reference to System.Web.Helpers
dynamic json = System.Web.Helpers.Json.Decode(@" ""Name"": ""Jon Smith"", ""Address"": ""City"": ""New York"", ""State"": ""NY"" , ""Age"": 42 ");
Console.WriteLine(json.Name);
Console.WriteLine(json.Address.State);
有关System.Web.Helpers.Json的更多信息,请参阅链接。
更新:如今获取Web.Helpers
的最简单方法是使用NuGet package。
如果您不关心早期的 Windows 版本,您可以使用 Windows.Data.Json
命名空间的类:
// minimum supported version: Win 8
JsonObject root = Windows.Data.Json.JsonValue.Parse(jsonString).GetObject();
Console.WriteLine(root["Name"].GetString());
Console.WriteLine(root["Address"].GetObject()["State"].GetString());
【讨论】:
为什么在我的 ASP.NET 网站 (4.5) 中看不到 System.Web.Helpers? XElement、XPathSelectElement 对我的 VisualStudio 来说是未知的。如何教育它? 好吧,你必须为相应的库添加引用(如上面的 cmets 中所写),请参阅article 了解更多信息。另外,这个question 可能很有趣。 我使用了这里描述的 Web.Helpers 方法,但遇到了一个问题,这篇文章解决了这个问题:***.com/questions/7066726/… 它与 WPF 一起使用。通过使用 System.Runtime.Serialization.Json 使用以下命名空间;使用 System.Xml.XPath;使用 System.Xml.Linq; Json.Net 不再是第三方组件。 Microsoft use it themselves these days. It's the default serilizer on Web API.【参考方案4】:如果您可以使用 .NET 4,请查看:http://visitmix.com/writings/the-rise-of-json (archive.org)
这是来自该网站的 sn-p:
WebClient webClient = new WebClient();
dynamic result = JsonValue.Parse(webClient.DownloadString("https://api.foursquare.com/v2/users/self?oauth_token=XXXXXXX"));
Console.WriteLine(result.response.user.firstName);
最后一个 Console.WriteLine 很可爱...
【讨论】:
抱歉,自从我最初回答以来,情况似乎发生了变化。我得四处看看,看看哪个库是正确的...... 期待您找到这个库。编辑:是不是这个:dynamicjson.codeplex.com? 我不知道 ElonU 类在这里是什么意思,但 Windows.Data.Json 中有“JsonValue”(仅适用于 Windows 8 及更高版本 - 很奇怪),系统中也有相同的“JsonValue” .Json 仍处于预览阶段,只有上帝知道它是否会出现。当谈到 Json 时,MS 让我感到困惑。【参考方案5】:另一个不需要任何第三方库但对 System.Web.Extensions 的引用的本机解决方案是 JavaScriptSerializer。自 3.5 以来,这不是一个新的但非常未知的内置功能。
using System.Web.Script.Serialization;
..
JavaScriptSerializer serializer = new JavaScriptSerializer();
objectString = serializer.Serialize(new MyObject());
返回
MyObject o = serializer.Deserialize<MyObject>(objectString)
【讨论】:
这很好,但是它需要网络组件,所以很遗憾它在 .NET 4.0 Client Profile 中不起作用,这是 Windows XP 的最后一个 .NET 版本。完全安装 .NET 是可能的,但很多人只坚持使用客户端配置文件。相比之下,即使在客户端配置文件中也支持 System.Runtime.Serialization.Json.DataContractJsonSerializer。 @fr34kyn01535:Windows XP 在台式机市场占有率第二高。这是相关的。 当我使用 JavaScriptSerializer 对我的对象进行反序列化时,它可以工作,但它错误地反序列化了我的日期。它应该是 2018 年 4 月 19 日上午 12:00,但反序列化为 2018 年 4 月 18 日下午 8:00。 NewtonSoft.Json.JsonConvert 按预期反序列化它。【参考方案6】:System.Text.Json
.NET core 3.0 内置了System.Text.Json
,这意味着您可以不使用使用第三方库来反序列化/序列化 JSON。
将您的类序列化为 JSON 字符串:
var json = JsonSerializer.Serialize(order);
要将 JSON 反序列化为强类型类:
var order = JsonSerializer.Deserialize<Order>(json);
所以如果你有一个像下面这样的课程:
public class Order
public int Id get; set;
public string OrderNumber get; set;
public decimal Balance get; set;
public DateTime Opened get; set;
var json = JsonSerializer.Serialize(order);
// creates JSON ==>
"id": 123456,
"orderNumber": "ABC-123-456",
"balance": 9876.54,
"opened": "2019-10-21T23:47:16.85",
;
var order = JsonSerializer.Deserialize<Order>(json);
// ==> creates the above class
需要注意的一点是System.Text.Json
不会自动处理camelCase
JSON 属性在使用您自己的代码时(但是,它在使用 MVC/WebAPI 时会请求和模型绑定器)。
要解决此问题,您需要将JsonSerializerOptions
作为参数传递。
JsonSerializerOptions options = new JsonSerializerOptions
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // set camelCase
WriteIndented = true // write pretty json
;
// pass options to serializer
var json = JsonSerializer.Serialize(order, options);
// pass options to deserializer
var order = JsonSerializer.Deserialize<Order>(json, options);
System.Text.Json 也可用于 .Net Framework 和 .Net Standard 作为 Nu-get 包 System.Text.Json
【讨论】:
没有课怎么办?如果您只是模糊地知道 json 数据将包含什么内容怎么办?或者密钥是否存在? @Cherona 使用JsonDocument.Parse
.【参考方案7】:
你也可以看看DataContractJsonSerializer
【讨论】:
这样更好,因为它与 .NET 3.5 兼容 它也比 JavaScriptSerializer 快很多, 仅供参考,.Net Core 不再支持此功能。【参考方案8】:System.Json 现在可以工作了...
安装nugethttps://www.nuget.org/packages/System.Json
PM> Install-Package System.Json -Version 4.5.0
示例:
// PM>Install-Package System.Json -Version 4.5.0
using System;
using System.Json;
namespace NetCoreTestConsoleApp
class Program
static void Main(string[] args)
// Note that JSON keys are case sensitive, a is not same as A.
// JSON Sample
string jsonString = "\"a\": 1,\"b\": \"string value\",\"c\":[\"Value\": 1, \"Value\": 2,\"SubObject\":[\"SubValue\":3]]";
// You can use the following line in a beautifier/JSON formatted for better view
// "a": 1,"b": "string value","c":["Value": 1, "Value": 2,"SubObject":["SubValue":3]]
/* Formatted jsonString for viewing purposes:
"a":1,
"b":"string value",
"c":[
"Value":1
,
"Value":2,
"SubObject":[
"SubValue":3
]
]
*/
// Verify your JSON if you get any errors here
JsonValue json = JsonValue.Parse(jsonString);
// int test
if (json.ContainsKey("a"))
int a = json["a"]; // type already set to int
Console.WriteLine("json[\"a\"]" + " = " + a);
// string test
if (json.ContainsKey("b"))
string b = json["b"]; // type already set to string
Console.WriteLine("json[\"b\"]" + " = " + b);
// object array test
if (json.ContainsKey("c") && json["c"].JsonType == JsonType.Array)
// foreach loop test
foreach (JsonValue j in json["c"])
Console.WriteLine("j[\"Value\"]" + " = " + j["Value"].ToString());
// multi level key test
Console.WriteLine("json[\"c\"][0][\"Value\"]" + " = " + json["c"][0]["Value"].ToString());
Console.WriteLine("json[\"c\"][0][\"Value\"]" + " = " + json["c"][1]["Value"].ToString());
Console.WriteLine("json[\"c\"][1][\"SubObject\"][0][\"SubValue\"]" + " = " + json["c"][1]["SubObject"][0]["SubValue"].ToString());
Console.WriteLine();
Console.Write("Press any key to exit.");
Console.ReadKey();
【讨论】:
在为 Json.NET/Newtonsoft.Json/"Newtson.Json" 和旧的 System 迭代获得无数结果之后,试图找到一个如何正确使用现代 System.Json 的示例将我带到这里.Json 早已被弃用。谢谢你。 这对我帮助很大。非常感谢。 对于 dotnet-core,从终端执行:“dotnet add package System.Json --version 4.5.0”【参考方案9】:使用此工具生成基于您的 json 的类:
http://json2csharp.com/
然后使用该类来反序列化您的 json。示例:
public class Account
public string Email get; set;
public bool Active get; set;
public DateTime CreatedDate get; set;
public IList<string> Roles get; set;
string json = @"
'Email': 'james@example.com',
'Active': true,
'CreatedDate': '2013-01-20T00:00:00Z',
'Roles': [
'User',
'Admin'
]
";
Account account = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine(account.Email);
// james@example.com
参考资料: https://forums.asp.net/t/1992996.aspx?Nested+Json+Deserialization+to+C+object+and+using+that+object https://www.newtonsoft.com/json/help/html/DeserializeObject.htm
【讨论】:
【参考方案10】:试试下面的代码:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL");
JArray array = new JArray();
using (var twitpicResponse = (HttpWebResponse)request.GetResponse())
using (var reader = new StreamReader(twitpicResponse.GetResponseStream()))
JavaScriptSerializer js = new JavaScriptSerializer();
var objText = reader.ReadToEnd();
JObject joResponse = JObject.Parse(objText);
JObject result = (JObject)joResponse["result"];
array = (JArray)result["Detail"];
string statu = array[0]["dlrStat"].ToString();
【讨论】:
这条线有什么作用吗...JavaScriptSerializer js = new JavaScriptSerializer();提前致谢。【参考方案11】:如果 JSON 是动态的,如下所示
"Items": [
"Name": "Apple",
"Price": 12.3
,
"Name": "Grape",
"Price": 3.21
],
"Date": "21/11/2010"
然后,一旦你从 NuGet 安装 NewtonSoft.Json
并将其包含在你的项目中,你就可以将其序列化为
string jsonString = "\"Items\": [\"Name\": \"Apple\",\"Price\": 12.3,\"Name\": \"Grape\",\"Price\": 3.21],\"Date\": \"21/11/2010\"";
dynamic DynamicData = JsonConvert.DeserializeObject(jsonString);
Console.WriteLine( DynamicData.Date); // "21/11/2010"
Console.WriteLine(DynamicData.Items.Count); // 2
Console.WriteLine(DynamicData.Items[0].Name); // "Apple"
来源:How to read JSON data in C# (Example using Console app & ASP.NET MVC)?
【讨论】:
【参考方案12】:我认为来自msdn 网站的以下内容有助于为您寻找的内容提供一些本机功能。请注意,它是为 Windows 8 指定的。下面列出了该站点的一个此类示例。
JsonValue jsonValue = JsonValue.Parse("\"Width\": 800, \"Height\": 600, \"Title\": \"View from 15th Floor\", \"IDs\": [116, 943, 234, 38793]");
double width = jsonValue.GetObject().GetNamedNumber("Width");
double height = jsonValue.GetObject().GetNamedNumber("Height");
string title = jsonValue.GetObject().GetNamedString("Title");
JsonArray ids = jsonValue.GetObject().GetNamedArray("IDs");
它利用Windows.Data.JSON 命名空间。
【讨论】:
不错,但“支持的最低客户端:Windows 8” 我认为它不再受支持,现在有 newtonsoft json dll icouldnt find windows.data.json @virtouso,正如 watbywbarif 指出的那样,它实际上是相当新的,但是来自Microsoft 的支持极少,仅适用于 Windows 8。【参考方案13】:你可以使用以下扩展
public static class JsonExtensions
public static T ToObject<T>(this string jsonText)
return JsonConvert.DeserializeObject<T>(jsonText);
public static string ToJson<T>(this T obj)
return JsonConvert.SerializeObject(obj);
【讨论】:
【参考方案14】:我认为我见过的最佳答案是@MD_Sayem_Ahmed。
您的问题是“如何使用 C# 解析 Json”,但您似乎想要解码 Json。如果你想解码,Ahmed 的回答很好。
如果您尝试在 ASP.NET Web Api 中完成此操作,最简单的方法是创建一个数据传输对象来保存您要分配的数据:
public class MyDto
public string Nameget; set;
public string Valueget; set;
您只需将 application/json 标头添加到您的请求中(例如,如果您使用的是 Fiddler)。 然后,您将在 ASP.NET Web API 中使用它,如下所示:
//controller method -- assuming you want to post and return data
public MyDto Post([FromBody] MyDto myDto)
MyDto someDto = myDto;
/*ASP.NET automatically converts the data for you into this object
if you post a json object as follows:
"Name": "SomeName",
"Value": "SomeValue"
*/
//do some stuff
这在我使用 Web Api 时帮助了我很多,让我的生活变得超级轻松。
【讨论】:
【参考方案15】: string json = @"
'Name': 'Wide Web',
'Url': 'www.wideweb.com.br'";
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
dynamic j = jsonSerializer.Deserialize<dynamic>(json);
string name = j["Name"].ToString();
string url = j["Url"].ToString();
【讨论】:
***.com/questions/6620165/how-can-i-parse-json-with-c/…【参考方案16】:var result = controller.ActioName(objParams);
IDictionary<string, object> data = (IDictionary<string, object>)new System.Web.Routing.RouteValueDictionary(result.Data);
Assert.AreEqual("Table already exists.", data["Message"]);
【讨论】:
你最好解释你的解决方案,而不是仅仅发布一些代码行。你可以阅读How do I write a good answer。 不要忘记在您的项目引用中包含System.Web
。【参考方案17】:
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(user)))
// Deserialization from JSON
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(UserListing))
DataContractJsonSerializer(typeof(UserListing));
UserListing response = (UserListing)deserializer.ReadObject(ms);
public class UserListing
public List<UserList> users get; set;
public class UserList
public string FirstName get; set;
public string LastName get; set;
【讨论】:
以上是关于如何使用 C# 解析 JSON?的主要内容,如果未能解决你的问题,请参考以下文章