zoukankan      html  css  js  c++  java
  • C#Json序列化和反序列化

    1、动态决定数据是否要序列化

      我的需求是这样的,我用了一款数据库的组件叫Dos.ORM,确实方便了不少,但是在用的时候,我发现一个问题,比如我定义的表中有一个字段添加时间,修改时间,这些都是默认的,在添加的时候,不需要赋值,但是我从前端传过来,就会是一个DateTime.MinValue。我不希望去更改它。但是我从数据库里面查询字段的时候,我又希望获取这些数据。所以不能简单的在Model上面加上是否序列化的属性。

      下面是我的JsonHelper类

    using Help.DataService.Business.Common;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Help.DataService.Business
    {
        public static class JsonHelper
        {
            public static string SerializeObject(object param)
            {
                if (param != null)
                {
                    return JsonConvert.SerializeObject(param);
                }
    
                return string.Empty;
            }
    
            public static T DeserializeObject<T>(string json) where T : class
            {
                if (!string.IsNullOrEmpty(json))
                {
                    return JsonConvert.DeserializeObject<T>(json);
                }
    
                return default(T);
            }
    
            public static RESULT ParseModel<INPUT, RESULT>(INPUT data)
                where INPUT : class
                where RESULT : class
            {
                if (data == null)
                {
                    return null;
                }
    
                var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
                string[] props = { "ModifyTime", "AddTime" };
                jSetting.ContractResolver = new LimitPropsContractResolver(props, false);
    
                string json = JsonConvert.SerializeObject(data, jSetting);
    
                if (!string.IsNullOrEmpty(json))
                {
                    // 空值和默认值,就不需要反序列化,Dos.ORM组件里面如果DateTime为0001-01-01的话,操作数据库会不成功
                    return JsonConvert.DeserializeObject<RESULT>(json, jSetting);
                }
    
                return default(RESULT);
            }
    
            public static R ParseViewModel<I, R>(I data)
                where I : class
                where R : class
            {
                string json = SerializeObject(data);
                return DeserializeObject<R>(json);
            }
        }
    }
    LimitPropsContractResolver类的代码如下:

    using Newtonsoft.Json.Serialization;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Help.DataService.Business.Common
    {
        /// <summary>
        /// 动态决定属性是否序列化
        /// </summary>
        public class LimitPropsContractResolver : DefaultContractResolver
        {
            /// <summary>
            /// 属性列表
            /// </summary>
            private string[] props = null;
    
            /// <summary>
            /// 是否包含
            /// </summary>
            private bool retain;
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="props">props</param>
            /// <param name="isretain">isretain(包含还是排除)</param>
            public LimitPropsContractResolver(string[] props, bool isretain = true)
            {
                this.props = props;
                this.retain = isretain;
            }
    
            protected override IList<JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
            {
                IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
    
                if (props == null || props.Length == 0)
                {
                    return list;
                }
    
                // 只列出清单保留的属性
                var ret = list.Where(p =>
                {
                    if (retain)
                    {
                        return this.props.Contains(p.PropertyName);
                    }
                    else
                    {
                        return !this.props.Contains(p.PropertyName);
                    }
                }).ToList();
    
                return ret;
            }
        }
    }

    2、用C#调java的服务。

      结果报错为数据没有查到,想不通,后来调试java代码发现,又是反序列化问题。因为C#的代码是第一个字母大写,java代码是第一个字母小写,这样就导致反序列化之后,java完全没有获取到任何参数,虽然C#已经传递过去了。在不改变java代码的前提下,我只能改C#代码了。好在有现成的方法,不过不是很常用,如下:

    CamelCasePropertyNamesContractResolver cal = new CamelCasePropertyNamesContractResolver();
    JsonSerializerSettings setting = new JsonSerializerSettings();
    setting.ContractResolver = cal;
    string json = JsonConvert.SerializeObject(vo, setting);

    3、相关资料

    Newtonsoft.Json高级用法

  • 相关阅读:
    现代软件工程的构建之法
    How do I Check for Duplicate Items in a ListView?
    (转)aspxgridview记录的批量修改
    vs2010简体中文旗舰版智能感知,中文提示,英文提示变化的问题
    (转)怎样成为一名Android开发者
    It’s Not Too Late to Learn How to Code
    (转)手机屏幕VGA QVGA HVGA WVGA区别
    (转)CodeSmithSchemaExplorer类结构详细介绍
    (转)C#控件命名规范
    DataReader 绑定DataGridView的方式
  • 原文地址:https://www.cnblogs.com/tianxue/p/5721494.html
Copyright © 2011-2022 走看看