【C#】使用Json.NET(newtonsoft)解析Json
最近做的WPF项目中,需要一个C#下的Json实现。
在Json的官网http://www.json.org/中查找,可见C#的Json工具主要有如下:
尝试了排在最前面的fastJSON,反序列化时出了些问题,也没找到文档和案例,就改用了Json.NET。为啥用这个,因为在Visual Studio的NuGet中搜json时,出来的第一个就是它。。。
(话说C#下的fastJSON由于其命名,某度上搜到的大多是阿里的Java实现https://github.com/alibaba/fastjson,蛋疼。。。)
做WPF桌面应用的客户端,数据由服务端以Json的形式传过来,所以先搞Json的反序列化,
即 Json –> Object。
关于工具Json.NET:
- 官网:http://www.newtonsoft.com/json
- Github:https://github.com/JamesNK/Newtonsoft.Json
- 文档及案例:http://www.newtonsoft.com/json/help/html/Samples.htm
现在假设收到的Json格式是下面这样的:
[
{
"City": "南宁",
"Community": [
"南宁A小区",
"南宁B小区",
"南宁C小区"
]
},
{
"City": "柳州",
"Community": [
"柳州A小区",
"柳州B小区",
"柳州C小区"
]
},
{
"City": "桂林",
"Community": [
"桂林A小区",
"桂林B小区",
"桂林C小区"
]
}
]
- Json格式的一个在线检验网站:http://www.bejson.com/
- 如果是其他格式,参考案例:http://www.newtonsoft.com/json/help/html/SerializeObject.htm
现在,根据文档中的这个案例:
http://www.newtonsoft.com/json/help/html/ReadJsonWithJsonTextReader.htm
string json = @"{
'CPU': 'Intel',
'PSU': '500W',
'Drives': [
'DVD read/writer'
/*(broken)*/,
'500 gigabyte hard drive',
'200 gigabype hard drive'
]
}";
JsonTextReader reader = new JsonTextReader(new StringReader(json));
while (reader.Read())
{
if (reader.Value != null)
{
Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value);
}
else
{
Console.WriteLine("Token: {0}", reader.TokenType);
}
}
// Token: StartObject
// Token: PropertyName, Value: CPU
// Token: String, Value: Intel
// Token: PropertyName, Value: PSU
// Token: String, Value: 500W
// Token: PropertyName, Value: Drives
// Token: StartArray
// Token: String, Value: DVD read/writer
// Token: Comment, Value: (broken)
// Token: String, Value: 500 gigabyte hard drive
// Token: String, Value: 200 gigabype hard drive
// Token: EndArray
// Token: EndObject
思路:使用JsonTextReader类,判断reader.TokenType和reader.Value来解析并处理。
首先根据Json数据,构建一个C#的数据类。
CityAndCommunity.cs:
class CityAndCommunity
{
public string City { get; set; }
public string[] Community { get; set; }
public override string ToString()
{
if (Community != null)
{
string communityStr = "";
for (int i = 0; i < Community.Length; i++)
{
if (i != Community.Length - 1)
{
communityStr += Community[i] + " , ";
}
else
{
communityStr += Community[i].ToString();
}
}
return "==============================\n City = "
+ City + " , communityStr = " + communityStr
+ "\n ======================================";
}
return base.ToString();
}
}
对应的解析方法:
class SystemUtils
{
/// <summary>
/// Json --> Object
/// </summary>
public static void GetCityAndCommunityStringData()
{
string json = SystemUtils.GetJsonString(); // 获取到Json字符串
List<CityAndCommunity> list = new List<CityAndCommunity>();
List<string> communitiesList = new List<string>(); // 用于存一个城市里的多个小区,最后转成字符数组string[]
CityAndCommunity obj = null;
bool isCommunity = false; // 用于判断读到的是否为数组内容,否则是城市名!
System.Console.WriteLine("------------------------------");
JsonTextReader reader = new JsonTextReader(new StringReader(json));
while (reader.Read())
{
if (reader.Value != null) // 有内容
{
// Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value);
if (reader.TokenType == JsonToken.String)
{
if (isCommunity)
{
// 是社区组
communitiesList.Add(reader.Value.ToString());
}
else
{
// 是城市名
obj.City = reader.Value.ToString();
}
}
}
else
{
// Console.WriteLine("Token: {0}", reader.TokenType);
if (reader.TokenType == JsonToken.StartObject)
{
isCommunity = false;
obj = new CityAndCommunity();
}
else if (reader.TokenType == JsonToken.StartArray)
{
// Json从开始到第一个对象开始,连续有两个[开始符号,但这里无所谓,可以不用flag分开处理
communitiesList = new List<string>();
isCommunity = true;
}
else if (reader.TokenType == JsonToken.EndArray)
{
if (communitiesList != null) // Json从最后一个对象结束到整个字符串的结束,连续有两个]结束符
{
obj.Community = communitiesList.ToArray();
communitiesList = null;
isCommunity = false;
}
}
else if (reader.TokenType == JsonToken.EndObject)
{
list.Add(obj);
obj = null;
}
}
}
System.Console.WriteLine("------------------------------");
System.Console.WriteLine("list.Count = " + list.Count);
System.Console.WriteLine("------------------------------");
for (int i = 0; i < list.Count; i++)
{
System.Console.WriteLine(list[i].ToString());
}
}
}
运行后打印结果如下:
------------------------------
Token: StartArray
Token: StartObject
Token: PropertyName, Value: City
Token: String, Value: 南宁
Token: PropertyName, Value: Community
Token: StartArray
Token: String, Value: 南宁A小区
Token: String, Value: 南宁B小区
Token: String, Value: 南宁C小区
Token: EndArray
Token: EndObject
Token: StartObject
Token: PropertyName, Value: City
Token: String, Value: 柳州
Token: PropertyName, Value: Community
Token: StartArray
Token: String, Value: 柳州A小区
Token: String, Value: 柳州B小区
Token: String, Value: 柳州C小区
Token: EndArray
Token: EndObject
Token: StartObject
Token: PropertyName, Value: City
Token: String, Value: 桂林
Token: PropertyName, Value: Community
Token: StartArray
Token: String, Value: 桂林A小区
Token: String, Value: 桂林B小区
Token: String, Value: 桂林C小区
Token: EndArray
Token: EndObject
Token: EndArray
------------------------------
list.Count = 3
------------------------------
==============================
City = 南宁 , communityStr = 南宁A小区 , 南宁B小区 , 南宁C小区
======================================
==============================
City = 柳州 , communityStr = 柳州A小区 , 柳州B小区 , 柳州C小区
======================================
==============================
City = 桂林 , communityStr = 桂林A小区 , 桂林B小区 , 桂林C小区
======================================
注意:以上解析方法是通过对照着打印Json的解析结果来写的,所以不具有通用性!
为了便于理解,Json格式和解析结果的对应关系如下:
一些其他参考:
http://blog.csdn.net/coolszy/article/details/8606803
http://blog.csdn.net/joyhen/article/details/24805899
2016.12.6傍晚 重要更新:
我发现自己就特么是个大写的SB啊!!!!!
看Json.NET文档看到了下面这个例子:
http://www.newtonsoft.com/json/help/html/DeserializeObject.htm
顺便截个图:
从例子可以看出,Json.NET已经实现了属性自动映射!!!
根据测试,映射规则是:
- 类中的属性名与Json中的Key值相同。
- 大小写不敏感。
- 属性的先后顺序无关。
对于当前的需求,可以参考反序列化Dictionary类的例子:
所以代码可以简化为:
class SystemUtils
{
/// <summary>
/// Json --> Object
/// </summary>
public static void GetCityAndCommunityStringData()
{
string json = SystemUtils.GetJsonString(); // 获取到Json字符串
new list<CityAndCommunity> = JsonConvert.DeserializeObject<List<CityAndCommunity>>(json);
System.Console.WriteLine("------------------------------");
System.Console.WriteLine("城市数量:list.Count = " + list.Count);
System.Console.WriteLine("------------------------------");
for (int i = 0; i < list.Count; i++)
{
System.Console.WriteLine(list[i].ToString());
}
}
}
运行结果如下:
------------------------------
list.Count = 3
------------------------------
==============================
City = 南宁 , communityStr = 南宁A小区 , 南宁B小区 , 南宁C小区
======================================
==============================
City = 柳州 , communityStr = 柳州A小区 , 柳州B小区 , 柳州C小区
======================================
==============================
City = 桂林 , communityStr = 桂林A小区 , 桂林B小区 , 桂林C小区
======================================
总结:Json.NET已经实现了属性自动映射,很强大很好用。最上面写的那一大坨垃圾代码也留在这篇博客中吧,就当作是记录下学习的过程。 ( ´_ゝ`)
【C#】使用Json.NET(newtonsoft)解析Json的更多相关文章
- 使用Newtonsoft.Json.dll(JSON.NET)动态解析JSON、.net 的json的序列化与反序列化(一)
在开发中,我非常喜欢动态语言和匿名对象带来的方便,JSON.NET具有动态序列化和反序列化任意JSON内容的能力,不必将它映射到具体的强类型对象,它可以处理不确定的类型(集合.字典.动态对象和匿名对象 ...
- [Xamarin] 調用JSON.net 來解析JSON (转帖)
上一篇文章我們提到了透過WebClient從Facebook 拿到我的JSON資料 再來我們要怎麼解析JSON格示呢?在.net 中,我們很孰悉的JSON.net,沒錯,我們依然可以在Xamarin中 ...
- 《项目经验》--后台一般处理程序向前台JS文件传递JSON,JS解析JSON,将数据显示在界面--显示在DropDownList 或 显示在动态创建的table中
http://blog.csdn.net/mazhaojuan/article/details/8599167 先看一下我要实现的功能界面: 这篇文章主要介绍:后台一般处理程序把从数据库查找的数据,转 ...
- Xamarin 调用JSON.net来解析JSON 转(Model) json2csharp.com/
https://www.cnblogs.com/zjoch/p/4458516.html 再来我们要怎么解析JSON格示呢?在.net 中,我们很孰悉的JSON.net,没错,我们依然可以在Xam ...
- Xamarin调用JSON.net来解析JSON
https://www.cnblogs.com/zjoch/p/4458516.html 再来我们要怎么解析JSON格示呢?在.net 中,我们很孰悉的JSON.net,没错,我们依然可以在X ...
- Json介绍以及解析Json
首先,介绍一下Json字串,以下Json的介绍引用网上资料. 简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应 ...
- 大话JSON之Gson解析JSON
(三)解析Json数组(多条Json数据) 比如有如下Json数据: [{'name':'John', 'grade':[{'course':'English','score':100},{'cour ...
- php生成json和js解析json
php生成json $value=array("name"=>"dfas");echo json_encode($value); js解析json var ...
- Java中使用org.json和json-lib解析JSON
文章目录 [隐藏] 一.JavaProject中org.json解析JSON 1.JSON的org.son-api下载 1)JSON网址 2)JSON的java解析org.json-api网址 3) ...
- C# JObject解析Json(多方法解析Json 二)
下载Newtonsoft.Json,添加引用 记得using Newtonsoft.Json.Linq; //用JObject解析 string json = "{\"offlin ...
随机推荐
- 修改Cygwin的默认启动路径
原先启动Cygwin后,pwd显示: C:\Documents and Settings\Administrator@IBM-EBDC0EAC4B7 ~$ pwdC:\Documents and Se ...
- ant入门程序
一. ant简单介绍 Ant是apache的一个核心项目, 它的作用是项目自己主动化构建, 由于它内置了Javac.Java.创建文件夹.拷贝文件等功能, 直接执行build.xml文件就能够编译我们 ...
- android.webkit.WebView/WebViewClient/WebChromeClient
使用android.webkit.WebView控件 在xml布局文件中定义 <WebView android:id="@+id/webkit01" android: ...
- XMLHttpRequest cannot load ...谷歌浏览器跨域问题
HTML页面通过Ajax调用公网web服务时,浏览器请求发送成功,但是响应的 xhr.status==0,控制台报错如下 XMLHttpRequest cannot load http://ws.we ...
- [转载]SVN权限设置具体实例
原文地址:SVN权限设置具体实例作者:白菜豆腐 1 背景假设 厦门央瞬公司是一家电子元器件设备供应商,其中有个ARM部门,专门负责ARM芯片的方案设计.销售,并在北京.上海各设立了一个办事处.对于 ...
- HDUOJ----4509湫湫系列故事——减肥记II
湫湫系列故事——减肥记II Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- Linux命令-防火墙命令:iptables
iptables详解--转 查看防火墙设置: 第一种方式: cat /etc/sysconfig/iptables 第二种方式: iptables -L -n -v 设置防火墙: 第一种方式: ipt ...
- AjaxPro实现异步调用,解决浏览器假死及超时问题
平时使用AjaxPro的时候基本上非常easy var msg = UseClass.Method(argument).value; 由于后台响应比較慢,所以加了个"loading" ...
- RTB竞价中的cookie mapping技术
首先通过一些关键词解释普及或者回顾一下背景, ADX: Ad exchange的简称.一般特指Ad exchange平台模块 DMP: Data Management Platform的简称.DMP存 ...
- php长链接
php 连接 mysql 是分为两步走的第一步:建立 php 到 mysql 服务器的 tcp/ip 通道 物理通道第二步:登录 mysql 服务器,建立到数据库的通道 逻辑通道 无论是长连接还是短连 ...