C#Json序列化和反序列化 1、动态决定数据是否要序列化 2、用C#调java的服务。 3、相关资料

  我的需求是这样的,我用了一款数据库的组件叫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高级用法