如何在没有 JSON.NET 库的情况下解析 JSON?
Posted
技术标签:
【中文标题】如何在没有 JSON.NET 库的情况下解析 JSON?【英文标题】:How to parse JSON without JSON.NET library? 【发布时间】:2012-03-23 07:21:55 【问题描述】:我正在尝试在 Visual Studio 2011 上为 Windows 8 构建 Metro 应用程序。
虽然我正在尝试这样做,但在没有 JSON.NET
库的情况下如何解析 JSON
时遇到了一些问题(它还不支持 Metro 应用程序)。
无论如何,我想解析这个:
"name":"Prince Charming",
"artist":"Metallica",
"genre":"Rock and Metal",
"album":"Reload",
"album_image":"http:\/\/up203.siz.co.il\/up2\/u2zzzw4mjayz.png",
"link":"http:\/\/f2h.co.il\/7779182246886"
【问题讨论】:
您可以像我们这些人在JSON.NET
和其他库出现之前所做的那样使用字符串操作来做到这一点。
使用 javascriptSerializer。看看这个答案:***.com/questions/8405458/…
你不应该问这个,MS 并没有表现出对 Json 那样的爱。在System.Web.Helpers
中有Json
,在System.ServiceModel.Web
中有JsonQueryStringConverter
,在System.Web.Script.Serialization
中有JavascriptSerializer
,在DataContractJsonSerializer
在System.Runtime.Serialization.Json
... 一点也不混乱。
Heck MS 甚至决定在其 ASP.NET Web API 中包含第三方 Json.NET
。如果您认为这还不够,MS 正在提出System.Json
,但目前不适合消费。而Windows 8是MS的特例,所以Windows.Data.Json
中也有JsonValue
,仅适用于Windows 8及以上。
截至 2016 年底:似乎 Microsoft has embraced Json.NET 并可能放弃了从未正式发布的 System.Json
:msdn.microsoft.com/en-us/library/… 谈论“预览”和 Nuget package 两者(仍然)标记为“Beta”并且已未列出,表明已弃用。 (有一个已发布的System.Json
,但它仅适用于 Silverlight)。
【参考方案1】:
您可以使用在 .NET 4.5 中添加的 System.Json Namespace 中的类。您需要添加对System.Runtime.Serialization 程序集的引用
JsonValue.Parse() Method 解析 JSON 文本并返回 JsonValue:
JsonValue value = JsonValue.Parse(@" ""name"":""Prince Charming"", ...");
如果您传递带有 JSON 对象的字符串,您应该能够将值转换为 JsonObject:
using System.Json;
JsonObject result = value as JsonObject;
Console.WriteLine("Name .... 0", (string)result["name"]);
Console.WriteLine("Artist .. 0", (string)result["artist"]);
Console.WriteLine("Genre ... 0", (string)result["genre"]);
Console.WriteLine("Album ... 0", (string)result["album"]);
这些类与System.Xml.Linq Namespace 中的类非常相似。
【讨论】:
您需要添加对 System.Runtime.Serialization 程序集的引用。 使用 Nuget 安装 system.json : Install-Package System.Json 如果找不到包,请确保添加版本号。示例:PM> Install-Package System.Json -Version 4.0.20126.16343
。在此处查找当前版本:nuget.org/packages/System.Json
System.Json 仍处于测试阶段,因此 Nuget 包似乎是获取它的方法。它不是内置在最新的完整 Framework V 4.5.1 中。就我个人而言,我喜欢 Json.Net 的 API,它比 Windows.Data.Json 或 System.Json 更简洁、更快。见james.newtonking.com/json/help/html/…
找不到system.json【参考方案2】:
我使用它...但从未做过任何 Metro 应用程序开发,所以我不知道对您可用的库有任何限制。 (注意,你需要将你的类标记为 DataContract 和 DataMember 属性)
public static class JSONSerializer<TType> where TType : class
/// <summary>
/// Serializes an object to JSON
/// </summary>
public static string Serialize(TType instance)
var serializer = new DataContractJsonSerializer(typeof(TType));
using (var stream = new MemoryStream())
serializer.WriteObject(stream, instance);
return Encoding.Default.GetString(stream.ToArray());
/// <summary>
/// DeSerializes an object from JSON
/// </summary>
public static TType DeSerialize(string json)
using (var stream = new MemoryStream(Encoding.Default.GetBytes(json)))
var serializer = new DataContractJsonSerializer(typeof(TType));
return serializer.ReadObject(stream) as TType;
所以,如果你有这样的课程......
[DataContract]
public class MusicInfo
[DataMember]
public string Name get; set;
[DataMember]
public string Artist get; set;
[DataMember]
public string Genre get; set;
[DataMember]
public string Album get; set;
[DataMember]
public string AlbumImage get; set;
[DataMember]
public string Link get; set;
那你就这样用吧……
var musicInfo = new MusicInfo
Name = "Prince Charming",
Artist = "Metallica",
Genre = "Rock and Metal",
Album = "Reload",
AlbumImage = "http://up203.siz.co.il/up2/u2zzzw4mjayz.png",
Link = "http://f2h.co.il/7779182246886"
;
// This will produce a JSON String
var serialized = JSONSerializer<MusicInfo>.Serialize(musicInfo);
// This will produce a copy of the instance you created earlier
var deserialized = JSONSerializer<MusicInfo>.DeSerialize(serialized);
【讨论】:
如何使用它?它一直问我要 TType,那是什么? 如果你的类型(类)被称为 MyType,你会像这样使用它: JSONSerializer对于那些没有 4.5 的人,这是我的读取 json 的库函数。它需要对System.Web.Extensions
的项目引用。
using System.Web.Script.Serialization;
public object DeserializeJson<T>(string Json)
JavaScriptSerializer JavaScriptSerializer = new JavaScriptSerializer();
return JavaScriptSerializer.Deserialize<T>(Json);
通常情况下,json是根据合同写出来的。该合同可以而且通常会被编入一个类 (T
)。有时您可以从 json 中取出一个单词并搜索对象浏览器以找到该类型。
示例用法:
给定 json
"logEntries":[],"value":"My Code","text":"My Text","enabled":true,"checkedIndices":[],"checkedItemsTextOverflows":false
您可以将其解析为 RadComboBoxClientState
对象,如下所示:
string ClientStateJson = Page.Request.Form("ReportGrid1_cboReportType_ClientState");
RadComboBoxClientState RadComboBoxClientState = DeserializeJson<RadComboBoxClientState>(ClientStateJson);
return RadComboBoxClientState.Value;
【讨论】:
【参考方案4】:您是否尝试过使用 JavaScriptSerializer
?
还有DataContractJsonSerializer
【讨论】:
不,你能解释一下那是什么吗?谢谢老兄 DataContract: msdn.microsoft.com/en-us/library/bb908432.aspx JavaScriptSerializer: msdn.microsoft.com/en-us/library/… 回复JavaScriptSerializer
:在撰写本文时,其MSDN page 建议改用Json.NET。【参考方案5】:
我需要一个没有任何第三方依赖或 nuget 的 JSON 序列化器和反序列化器,它可以支持旧系统,因此您不必在 Newtonsoft.Json、System.Text.Json、DataContractSerializer、JavaScriptSerializer 等之间进行选择,具体取决于在目标平台上。
所以我在这里启动了这个开源 (MIT) 项目:
https://github.com/smourier/ZeroDepJson
它只是一个 C# 文件 ZeroDepJson.cs
,兼容 .NET Framework 4.x 到 .NET Core 和 .NET 5。
请注意,它可能不如上述所有库(尤其是在性能方面),但它应该还算不错且无摩擦。
【讨论】:
【参考方案6】:您可以使用DataContractJsonSerializer
。有关详细信息,请参阅此link。
【讨论】:
我用这段代码试过了 DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Song));歌曲项 = (Song)ser.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(song))); Debug.WriteLine(item.name); 它给了我一个错误 错误是类型'Test1.Song'不能被序列化。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。如果该类型是一个集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。有关其他支持的类型,请参阅 Microsoft .NET Framework 文档。 @EliRevah - 您需要使用类的 [DataContract] 属性定义反序列化的数据协定,并为每个成员添加 [DataMember] 属性。【参考方案7】:using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
namespace OTL
/// <summary>
/// Before usage: Define your class, sample:
/// [DataContract]
///public class MusicInfo
///
/// [DataMember(Name="music_name")]
/// public string Name get; set;
/// [DataMember]
/// public string Artistget; set;
///
/// </summary>
/// <typeparam name="T"></typeparam>
public class OTLJSON<T> where T : class
/// <summary>
/// Serializes an object to JSON
/// Usage: string serialized = OTLJSON<MusicInfo>.Serialize(musicInfo);
/// </summary>
/// <param name="instance"></param>
/// <returns></returns>
public static string Serialize(T instance)
var serializer = new DataContractJsonSerializer(typeof(T));
using (var stream = new MemoryStream())
serializer.WriteObject(stream, instance);
return Encoding.Default.GetString(stream.ToArray());
/// <summary>
/// DeSerializes an object from JSON
/// Usage: MusicInfo deserialized = OTLJSON<MusicInfo>.Deserialize(json);
/// </summary>
/// <param name="json"></param>
/// <returns></returns>
public static T Deserialize(string json)
if (string.IsNullOrEmpty(json))
throw new Exception("Json can't empty");
else
try
using (var stream = new MemoryStream(Encoding.Default.GetBytes(json)))
var serializer = new DataContractJsonSerializer(typeof(T));
return serializer.ReadObject(stream) as T;
catch (Exception e)
throw new Exception("Json can't convert to Object because it isn't correct format.");
【讨论】:
【参考方案8】:很久以前我写了一个小函数来做这个,它需要System.Runtime.Serialization.Json
命名空间。
要使用你需要调用
JConvert<string,object>(str); //to Parse string to non anonymous <object>
JConvert<object,string>(obj); //to convert <obj> to string
看看这是否适合你。它适用于小数据集,但没有对大数据源进行测试。
// Json Serializer without NewtonSoft
public static class JsonHelper
public static R JConvert<P,R>(this P t)
if(typeof(P) == typeof(string))
var return1 = (R)(JsonDeserializer<R>(t as string));
return return1;
else
var return2 = (JsonSerializer<P>(t));
R result = (R)Convert.ChangeType(return2, typeof(R));
return result;
private static String JsonSerializer<T>(T t)
var stream1 = new MemoryStream();
var ser = new DataContractJsonSerializer(typeof(T));
ser.WriteObject(stream1, t);
stream1.Position = 0;
var sr = new StreamReader(stream1);
return (sr.ReadToEnd());
private static T JsonDeserializer<T>(string jsonString)
T deserializedUser = default(T);
var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
var ser = new DataContractJsonSerializer(typeof(T));
deserializedUser = (T)ser.ReadObject(ms);// as T;
ms.Close();
return deserializedUser;
【讨论】:
以上是关于如何在没有 JSON.NET 库的情况下解析 JSON?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有外部库的情况下在 React 中实现 Google Maps JS API?
在没有 JS 库的情况下在 <canvas> 上为 spritesheet 设置动画 [重复]