C#中的Json操作

原创 2017年08月12日 11:37:26

随着JSON越来越多的应用到IT领域,C#中再也不是XML一家独占的情况了。熟练的解析和构建JSON也是必备技能。目前我正在参与的ArcGIS Earth产品,其工作区的保存格式以及软件中的传输格式都是使用JSON。就在此分享一些浅显的经验吧。

工欲善其事必先利其器,对于C#一般使用Newtonsoft.Json就行了,如果使用python则用json,但对于C++,由于许可和效率的问题,选择会很多,对于开源软件,我比较推荐Jsoncpp。

基础使用

对于一般的类或者对象,使用JsonConvert.SerializeObject(yourObject)或者
JsonConvert.DeserializeObject<T>(jsonString)就行。示例如下:

using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace AboutJson
{
    public enum Country
    {
        CN,
        EN,
        US
    }
    public class Family 
    {
        public Country Country { set; get; }
        public string Dad { set; get; }
        public string Mum { set; get; }
        public List<string> Children { set; get; }
    }

    class Program
    {
        static private string TestSerializeObject(Family f)
        {
            return JsonConvert.SerializeObject(f);
        }

        static private Family TestDeserializeObject(string familyJson)
        {
            return JsonConvert.DeserializeObject<Family>(familyJson);
        }
        static void Main(string[] args)
        {
            Family f = new Family {
                Country = Country.US,
                Dad = "Mr Brown",
                Mum = "Mrs Brown",
                Children = new List<string>{"Lily", "Lucy"} };

            // The result will be
            // { "Country":2,"Dad":"Mr Brown","Mum":"Mrs Brown","Children":["Lily","Lucy"]}
            // But sometimes we need country like this : "Country" : "US"
            string familyJson = TestSerializeObject(f);

            Family f1 = TestDeserializeObject(familyJson);
        }
    }
}

但是有时候我们有一些特殊的需求,例如,某些字段在转换为Json的时候不输出,枚举需要转换为字符串而不是数字,某些字段的键值需要自定义和变量名不相同。。。

这时候,在不修改原始对象的情况下,最直接的办法是自己手动来构建和解析Json字符串。

其中涉及到的内容为,JObject(JToken,JArray)和基础数据类型的转换。示例如下:

        static private string ConstructJsonManually(Family f)
        {
            JObject familyObj = new JObject();
            JArray childrenObj = new JArray();
            familyObj["Dad"] = f.Dad;
            familyObj[nameof(Family.Mum)] = f.Mum;
            familyObj[nameof(Country)] = f.Country.ToString();
            foreach(var child in f.Children)
            {
                childrenObj.Add(child);
            }
            familyObj[nameof(f.Children)] = childrenObj;
            return familyObj.ToString(Formatting.None);
        }

        static private Family ParseJsonManually(string familyJson)
        {
            Family f = new Family();
            Country country = Country.CN;
            JObject familyObj = JObject.Parse(familyJson);
            if(familyObj[nameof(Country)] != null)
            {
                Enum.TryParse(familyObj[nameof(Country)].ToString(), true, out country);
                f.Country = country;
            }

            if(familyObj[nameof(Family.Dad)] != null)
            {
                f.Dad = familyObj[nameof(Family.Dad)].ToString();
            }

            if(familyObj[nameof(Country)] != null)
            {
                f.Mum = familyObj[nameof(Family.Mum)].ToString();
            }

            if(familyObj[nameof(Family.Children)] != null)
            {
                JArray childrenObj = (JArray)familyObj[nameof(Family.Children)];
                f.Children = new List<string>();
                foreach(var child in childrenObj)
                {
                    f.Children.Add(child.ToString());
                }
            }
            return f;
        }

调用结果是:

            // The result will be 
            // { "Dad":"Mr Brown","Mum":"Mrs Brown","Country":"US","Children":["Lily","Lucy"]
            string familyJsonManual = ConstructJsonManually(f);

            Family f2 = ParseJsonManually(familyJsonManual);

进阶用法

如果觉得手动构建解析工作量大,后期不好维护,并且有权限修改原始的类,则可以使用一些进阶的用法了。如JsonSerializerSettingsJsonProperty,但是这儿,我对此不做过多介绍,对于高阶使用,查阅第一手的官方文档更加重要。

我在这儿举三个常用情况的例子吧。输出的时候修改键值,输出字符串形式的枚举,选择性的输出某些字段。

    [JsonObject(MemberSerialization.OptOut)]
    public class FamilyEx
    {
        [JsonConverter(typeof(StringEnumConverter))]
        public Country Country { set; get; }
        [JsonProperty(PropertyName = "Father")]
        public string Dad { set; get; }
        [JsonIgnore]
        public string Mum { set; get; }
        public List<string> Children { set; get; }
    }

    // The result will be 
    // { "Country":"US","Father":"Mr Brown","Children":["Lily","Lucy"]}
    string familyJsonEx = JsonConvert.SerializeObject(fEx);

其中使用[JsonObject(MemberSerialization.OptOut)][JsonIgnore]来选择性输出。
使用[JsonConverter(typeof(StringEnumConverter))]来以字符串输出枚举值。
使用[JsonProperty(PropertyName = "Father")]将键值由Dad修改为Father

结语

更个性化定制的内容,建议查阅第一手官方文档。消除隐患。C#中处理Json还是很方便的,但是由于Json格式的多样性和用户输入的不确定性,请使用try catch来捕获和判断异常,以便log和给出人性化的用户提示。

完整代码,见GitHub

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

Struts2中操作JSON

使用struts-json插件生成json数据 在maven中添加 org.apache.struts struts2-json-...

PHP中JSON操作

生成json数据:json_encode对变量进行JSON编码。$value可以是数组也可以是对象。一维数组:浏览器结果: 多维数组:浏览器结果: 对象生成json:浏览器结果: json数据解...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

Java中JSON的操作

简介JSON:JavaScript对象表示法(JavaScript Object Notation)。 是储存和交换文本信息的语法。 JSON是轻量级的文本数据交换格式。 JSON独立于语言和平台。...

Qt中的JSON操作

JSON(JavaScript Object Notation,js对象标记)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据。简洁和...

JavaScript中的JSON操作

//数据过滤 document.write("数据过滤:"+""); var per = new Object; per.sex = "male"; per.age = 29; per.birthda...

java中的JSON操作

一·、JSON简介 JSON是JavaScript对象表示法,是存储和交换文本信息的语法。并且独立于语言和平台。类似于xml,比xml更小、更快、更易解析。———-二、JSON对象 ...

JAVA中操作JSON数据(alibaba-fastjson)、javascript中操作JSON数据

json数据格式:{"name":"tom","age":23} key必须双引号引上,value如果是数字不用双引号 json类型的数组:[{"name":"tom","age&quo...

Json——js对Json的操作

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式。博主记得几年前在华为外包项目中有一个和Android应用交互的需求,Andr...

C++操作Json字符串

一、从字符串中读取JSON a.cpp ? 1 2 3 4 5 6 7 8 9 10 11 ...

C#JSON文件操作

首先声明,博主采用的是vs20151.配置json环境:配置json环境有俩种方法,一种是直接去官网下载包,导进vs中,一种是直接在vs中在线安装,自动配置(这里介绍第二种,直接上图) 在工程视...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)