Json.NET常用方法汇总(可解决日常百分之90的需求)_哈丨吅的博客-程序员秘密

技术标签: C#  Json.net  

0.Json.NET基础用法

  NuGet搜索Newtonsoft.Json下载并引用至项目。

  • (1)序列化实体类(将实体类对象序列化为Json字符串)
  • using System;
    using Newtonsoft.Json;
    
    namespace Json_NET_Test
    {
        /// <summary>
        /// 定义一个实体类
        /// </summary>
        public class Student
        {
            public string Name;
            public int Age;
            public string Class;
        }
        class Program
        {
            static void Main(string[] args)
            {
                //创建实体类对象           
                Student stu = new Student
                {
                    Name = "老王",
                    Age = 99,
                    Class = "三班"
                };
                //开始序列化
                string jsonStr = JsonConvert.SerializeObject(stu, Formatting.Indented);
                Console.WriteLine(jsonStr);
            }
        }
    }
  • (2)反序列化(将Json字符串反序列化为实体类对象)
  • using System;
    using Newtonsoft.Json;
    
    namespace Json_NET_Test
    {
        /// <summary>
        /// 定义一个实体类
        /// </summary>
        public class Student
        {
            public string Name;
            public int Age;
            public string Class;
        }
        class Program
        {
            static void Main(string[] args)
            {
                //Json字符串
                string jsonStr = "{"Name": "老王","Age": 99,"Class": "三班"}";
                //开始反序列化
                Student stu = JsonConvert.DeserializeObject<Student>(jsonStr);
            }
        }
    }

    1.序列化与反序列化时忽略某些属性

  • (1)忽略类内所有属性
  •   [JsonObject(MemberSerialization.OptIn)]用于在序列化与反序列化时忽略一个类里所有的属性,只有当在类内属性上打特性标签[JsonProperty]时才支持序列化与反序列化。所以[JsonObject(MemberSerialization.OptIn)]常用于与[JsonProperty]配合使用。

      例:

  • [JsonObject(MemberSerialization.OptIn)]
    public class Person
    {
        public int Age { get; set; }
    
        [JsonProperty]
        public string Name { get; set; }
    
        public string Sex { get; set; }
    
        public bool IsMarry { get; set; }
    
        public DateTime Birthday { get; set; }
    }

     

  • (2)序列化所有属性(默认)
  •   默认实体类上默认打着[JsonObject(MemberSerialization.OptOut)]特性标签(可以省略不写),如果要忽略某些属性,要在属性上打[JsonIgnore]。

      例:

  • [JsonObject(MemberSerialization.OptOut)]
    public class Person
    {
        public int Age { get; set; }
    
        public string Name { get; set; }
    
        public string Sex { get; set; }
    
        [JsonIgnore]
        public bool IsMarry { get; set; }
    
        public DateTime Birthday { get; set; }
    }

     

  • (3)动态控制实体类属性的是否忽略序列化(默认)
  •   当某些条件下需要序列化A属性和B属性,某些情况下需要忽略A属性与B属性,我们该怎么做?
      答:使用JsonSerializerSettings设置某实体类对象要忽略序列化的属性(配合if与else控制属性的动态忽略)。

      例:以下方式忽略p对象的Age属性与IsMarry属性:

  • JsonSerializerSettings jsetting=new JsonSerializerSettings();
      jsetting.ContractResolver = new LimitPropsContractResolver(new string[] { "Age", "IsMarry" });
      Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

    2.默认值处理

  • (1)设置属性默认值
  •   在属性上打 [DefaultValue("xxx")]

    3.空值处理

  • (1)不序列化为null的属性(使用JsonSerializerSettings方式)
  • ps:使用这种方式可能bool为false的也无法序列,最后的结果只包含Birthday、Sex、Name、Age。
  • Person p = new Person 
        { 
             room = null,
             Age = 10, 
             Name = "张三丰", 
             Sex = "男", 
             IsMarry = false, 
             Birthday = new DateTime(1991, 1, 2) 
        };
        JsonSerializerSettings jsetting=new JsonSerializerSettings();
        jsetting.NullValueHandling = NullValueHandling.Ignore;
        Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

     

  • (2)不序列化为null的属性(使用特性标签方式)
  • [JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
    public Room room { get; set; }

    4.序列化私有成员

      因为默认只序列化public的成员,所以如果想序列化private成员,要在实体类的属性上打[JsonProperty]标签。

  • [JsonProperty]
    private int Height { get; set; }

    5.自定义序列化名称

      在序列化与反序列化时可以自定义序列化出字符串的属性名称,如下代码可以将实体类的Name属性序列化为CName属性,并且可以将Json中的CName反序列化为当前实体类的Name属性。(双向)

  • [JsonProperty(PropertyName = "CName")]
    public string Name { get; set; }

    6.日期处理

  • (1)解决方案1:在可以动Model代码的情况下
  •   系统自带的DateTime会格式化成iso日期标准,但是实际使用过程中大多数使用的可能是yyyy-MM-dd 或者yyyy-MM-dd HH:mm:ss两种格式的日期,解决办法是可以将DateTime类型改成string类型自己格式化好,然后在序列化。

  • ps:代码思路是不去序列化StartTime属性,而去序列化string类型的m_StartTime属性(m_StartTime相当于StartTime属性的私有字段)。
      例:

  • [JsonProperty(PropertyName = "startTime")]//因为默认只序列化public属性,所以要打上JsonProperty标签并且声明名称
        private string m_StartTime{get;set;}
    
        [JsonIgnore]//这个标签用于在序列化与反序列化时忽略StartTime属性
        public DateTime StartTime
        {
            get{ return Convert.ToDateTime(m_StartTime); }
            set
            {
                DateTime time = value;
                m_StartTime = time.ToString("yyyy-MM-dd");//这里写自己想要的格式
            }
        }

     

  • (2)解决方案2:使用DateTimeConverterBase
  •   Json.Net提供了IsoDateTimeConverter日期转换这个类,可以通过JsnConverter实现相应的日期转换

  • [JsonConverter(typeof(IsoDateTimeConverter))]
    public DateTime Birthday { get; set; }

    但是IsoDateTimeConverter日期格式(yyyy-MM-ddTHH:mm:ss)不是我们想要的,我们可以继承该类实现自己的日期

  • public class ChinaDateTimeConverter : DateTimeConverterBase
        {
            private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" };
    
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                return dtConverter.ReadJson(reader, objectType, existingValue, serializer);
            }
    
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                dtConverter.WriteJson(writer, value, serializer);
            }
        }

    使用方式:

  • [JsonConverter(typeof(ChinaDateTimeConverter))]
    public DateTime Birthday { get; set; }

    7.以驼峰命名法序列化

      有时我们会碰到这种需求,比如我们代码里实体类型的属性名称均是以大写字母开头,如Name、StartTime等,但是要求我们序列出的Json字符串的属性名称要以小写字母开头,如name、startTime、endTime等。我们可以使用如下代码解决

  • JsonSerializerSettings setting = new JsonSerializerSettings();
    setting.ContracResolver = new CamelCasePropertyNamesContractResolver();
    string jsonStr = JsonConvert.Serializeobject(p, Newtonsoft.json.Formatting.Indented, setting);

    这样子的话,在序列实体类对象p的属性时,属性名称将由PersonName转换为personName。

  • 8.枚举的序列化
      枚举默认序列化为枚举的Int值,如果想要序列化为枚举string值,使用如下方式

  • [JsonConverter(typeof(StringEnumConverter))]
      public NotifyTypeEnum Type { get; set; }

    9.使用JsonConverter自定义属性序列化规则(json格式转换器)

  • (1)将属性值由double类型序列化时转为字符串类型
  • public class DoubleToStringConverter : JsonConverter
        {
            //表示反序列化时不执行该转换器
            public override bool CanRead => false;
            //表示序列化时执行该转换器
            public override bool CanWrite => true;
    
            //判断执行条件(当属性的值为double类型时才使用转换器)
            public override bool CanConvert(Type objectType)
            {
                return objectType == typeof(double);
            }
    
            //因为public override bool CanRead => false;,所以不用实现反序列化时的转换方法
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
    
            /// <summary>
            /// 序列化时执行的转换
            /// </summary>
            /// <param name="writer">可以用来重写值</param>
            /// <param name="value">属性的原值</param>
            /// <param name="serializer">就是那个serializer对象</param>
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                double v = (double)value;
                writer.WriteValue(v.ToString());
            }
        }
    使用方式:
  • [JsonConverter(typeof(DoubleToStringConverter))]
    public double Count{get;set;}

    ps:这样子,就可以把原本序列化出的Json字符串   Count : 12.3   转化为   Count : "12.3"
      ps:[JsonConverter(typeof(DoubleToStringConverter))]也可以打在类上,表示全局设置

  • (2)枚举转换为int字符串
  •   为什么要进行这样的转换呢?

      因为枚举类型在序列化时默认序列化为枚举的int类型,即如下代码:

  •  /// <summary>
        /// 自定义一个枚举类型
        /// </summary>
        public enum MyEnum
        {
            aaa = 1,
            bbb = 2,
            ccc = 3
        }
        /// <summary>
        /// 实体类(类内有一个枚举类型的属性MyEnumProp)
        /// </summary>
        public class Person
        {
            public MyEnum MyEnumProp { get; set; }
        }
        class Program
        {
    
            static void Main(string[] args)
            {
                Person p = new Person() { MyEnumProp = MyEnum.ccc };
                //Json字符串
                string jsonStr = JsonConvert.SerializeObject(p);
                //开始反序列化
                Console.WriteLine(jsonStr);
                Console.ReadLine();
            }
        }
    
    //输出:{"MyEnumProp ":3}

    有时候会有这样的需求,序列化出的属性值均要为字符串格式,即要将上图结果的3改为"3"。这时候就需要自定义转换了!

      代码如下:

 public class EnumToIntStringConverter : JsonConverter
    {
        //反序列化时不执行
        public override bool CanRead => false;
        //序列化时执行
        public override bool CanWrite => true;

        //控制执行条件(当属性的值为枚举类型时才使用转换器)
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Enum);
        }

        //因为public override bool CanRead => false;,所以不用实现反序列化时的转换方法
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 序列化时执行的转换
        /// </summary>
        /// <param name="writer">可以用来重写值</param>
        /// <param name="value">属性的原值</param>
        /// <param name="serializer">就是那个serializer对象</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            Enum e = (Enum)value;
            int v = Convert.ToInt32(e);
            writer.WriteValue(v.ToString());
        }
    }  

 

转载自:Newtonsoft—Json.NET常用方法简述 (lagou.com)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a549742320/article/details/117303977

智能推荐

java 限制https_本地Java程序访问HTTPs遇到的问题_weixin_39860919的博客-程序员秘密

本地测试程序需要访问HTTPs,String urlPath = "https://192.168.10.88/xxx/login?username=" + userName + "&amp;password=" +password;URL url= newURL(urlPath);connection=(HttpURLConnection)url.openConnection();connect...

BZOJ2238 mst(最小生成树+树链剖分)_bzoj树链剖分好题_Michael_GLF的博客-程序员秘密

传送门【题目分析】树剖好题。首先按题意做出最小生成树,如果做不出,那么所有询问都是&quot;Not connected&quot;。同样,如果删的是非生成树上的边,对答案不会造成影响,直接输出最小生成树的权值即可。那么考虑生成树上的边被删的情况:很明显,对于一个环上的所有边,如果删掉一条,剩下的点仍然会保持联通。所以这个环上的所有边都是可以互相替代的。按照这个思路,我们将所有非生成树...

Android基础(五)----Toast的简单使用_andanwubian的博客-程序员秘密

上一篇中讲述了如何建立一个活动(从空白开始),该篇简单介绍Toast的使用Toast是Android系统中的一种较好的提醒方式,可以将较短小的信息通知给用户,并在一段时间后消失,不占用屏幕空间。Toast使用方法:使用makeText()(该方法有三个参数)创建一个Toast对象,然后调用show()将Toast显示出来就可以了。Toast.makeText(Context co...

SpringCloud服务间调用_spring cloud测试类的路径和application包路径不一致需要怎么办_漫玥刚花的博客-程序员秘密

 SpringCloud服务间的调用有两种方式:RestTemplate和FeignClient。不管是什么方式,他都是通过REST接口调用服务的http接口,参数和结果默认都是通过jackson序列化和反序列化。因为Spring MVC的RestController定义的接口,返回的数据都是通过Jackson序列化成JSON数据。一、RestTemplate使用这种方式,只需要定义一个R...

iqooneo5隐藏应用方法分享(2021)_“neo5的隐藏功能怎么设置”_爱学习的小兔子的博客-程序员秘密

在我们的手机中难免会有一些隐私应用不想被别人看到。这时我们可以对该软件进行应用隐藏。那具体该怎么操作呢?不要着急换换早就为大家准备好了iqooneo5应用隐藏的详细方法。快来接着往下看看吧!iqooneo5隐藏应用方法分享1、打开手机设置。点击【指纹、面部与密码】。2、点击【隐私与应用加密】。设置好隐私密码。3、点击【应用隐藏】。4、开启需要隐藏应用的开关即可。...

窗口的位置:GetWindowRect与MoveWindow等_vb中的movewindow有什么用_超频化石鱼的博客-程序员秘密

父对话框的整个窗口区=父对话框客户区+父对话框标题栏区1. GetWindowRect()获取的是以屏幕左上角为(0,0)点的窗口区域,是屏幕坐标系。①  如果对父对话框调用GetWindowRect(),那么获取的矩形为父窗口在屏幕中的区域,其中矩形区含标题栏以及外边框。②  如果对控件调用GetWindowRect(),那么获取的矩形是控件在屏幕中的区域。注意在对话框的OnInitDialog...

随便推点

C++迭代器:const_iterator和const形式的iterator有什么区别?_涛歌依旧的博客-程序员秘密

从C语言走过来的猿们, 对指针已经很熟悉了, 也很清楚指向常量的指针和常指针的区别。 在本文中, 我们来学习一下C++中的迭代器, 顺便类比指针来学习一下指向常量的迭代器和常迭代器的区别。       其实, 迭代器很简单, 你就把它理解为一种类似指针的东西就行了, 毕竟指针的概率是广义的, 你的手指, 大拇指, 小拇指, 那就是个指针。 比如, 完全可以把vector::iterator理解

C语言中time函数_time( <1 ); time = localtime(<1);_Resines的博客-程序员秘密

<br />C语言中time函数<br />void main()<br />{  <br />struct tm *newtime;<br />char tmpbuf[128];<br /> time_t lt1;<br />    time(<1);<br />newtime = localtime(<1) ;<br />strftime(tmpbuf,128,"  year =%Y; month = %m;day =%d; /n",newtime);<br />printf(tmpbuf);<br /

解读TCP/UDP数据包(四):TCP数据包实例解析_tcp数据包解析_fzzmouse的博客-程序员秘密

1、一个完整的TCP数据包 11:43:26.893811 IP 10.135.1.108.39936 > 10.135.38.95.8090: P 1:247(246) ack 1 win 12 <nop,nop,timestamp 3216248128 3584896032>       0x0000: 4500 012a cfdf 4000 3d06 3016 0a87

STL函数对象及函数对象适配器【转】_happyprince的博客-程序员秘密

一 函数对象Functor    STL中提供了一元和二元函数的两种Functor,通过unary_function和binary_function提供了这两种不同参数数量的Functor的基本结构,在这两个类型中,分别内嵌定义一元和二元函数操作在模版推演的时候需要用到的typedef. //一元函数的定义为template&amp;lt;class _A, class _R&amp;gt;struc...

word 2016利用表格编排公式及编号_word表格公式编号_suxiaosususu的博客-程序员秘密

前言       利用word写文章时,不免需要用使用公式。插入公式和上节介绍的插入图表一样,也需要对其进行编号和交叉引用,但是插入公式也插入图表也不太一样,在这里介绍利用表格来插入公式并对其进行排版和编号,以做备忘。    操作过程      1、插入一个“一行三列”的表格,如下图;      2、全选表格,右击选择“表格属性”,目的是消除表格内字符和表格边界的距离,如下图;...

spring cloud集成 NACOS配置中心实现动态配置_nacos-config pom_抹香鲸之海的博客-程序员秘密

一、Nacos配置中心介绍Nacos提供了两种服务,一种是用于服务注册、发现的Naming Service,一种是用于配置中心、动态配置的Config Service,而他们底层均由core模块来支持。外层提供OpenAPI供客户端使用,并提供了User Console、Admin Console方便用户使用 。Nacos 并不是通过推的方式将服务端最新的配置信息发送给客户端的,而是客户端维护了一个长轮询的任务,定时去拉取发生变更的配置信息,然后将最新的数据推送给 Listener 的持有者。配置主要有

推荐文章

热门文章

相关标签