Newtonsoft.Json中的时间格式详解.

Newtonsoft.json是一款不错的序列化反序列化第三方组件,具体如何使用属于基础知识,此处不再讲解.看以下代码:

public class OutgameEntity
{
    public string orderid{get;set;}
    public DateTime? payTime { get; set; }
}

很简单的一个实体类

假如此时有一个url:http://www.xxx.xx/do.svc/xxx?data=,我们如果要把OutgameEntity实体类的值传过去,就需要反序列化对象为string字符串.

public static string JsonSerialize(T o)
{
   string str = JsonConvert.SerializeObject(o, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
   {
        NullValueHandling = NullValueHandling.Ignore
   });
   return str;
}
 
new WebClient().DownloadString(url,JsonSerialize(OutgameEntity));
 
此段代码看似没有任何问题.不过当你接收时,你会发现一点点问题.
"payTime":"\/Date(13884569650000800)\/".
如果这个参数值没有任何意义,那么我们可以忽略这个问题.但是作为程序员,特别是和别的公司进行对接的接口会出现这样的参数值,会给同行造成此人是菜鸟的心理.所以我们应该想办法解决这个不大不小的问题.
如何解决呢?
 
请看以下这个接口:
using Newtonsoft.Json.Schema;
using System;

namespace Newtonsoft.Json
{
    public abstract class JsonConverter
    {
        protected JsonConverter();

        public virtual bool CanRead { get; }
        public virtual bool CanWrite { get; }

        public abstract bool CanConvert(Type objectType);
        public virtual JsonSchema GetSchema();
        public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer);
        public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer);
    }
}
using Newtonsoft.Json;
using System;

namespace Newtonsoft.Json.Converters
{
    public abstract class DateTimeConverterBase : JsonConverter
    {
        protected DateTimeConverterBase();

        public override bool CanConvert(Type objectType);
    }
}

已经有了DatetimeConverterBse这个父类,那么要实现这个功能就比较好办.

我们去重写实现JsonConverter中的ReadJson和WriteJson方法,如下:

public class UnixDateTimeConverter : DateTimeConverterBase
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType != JsonToken.Integer)
        {
            throw new Exception(String.Format("日期格式错误,got {0}.", reader.TokenType));
        }
        var ticks = (long)reader.Value;
        var date = new DateTime(1970, 1, 1);
        date = date.AddSeconds(ticks);
        return date;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        long ticks;
        if (value is DateTime)
        {
            var epoc = new DateTime(1970, 1, 1);
            var delta = ((DateTime)value) - epoc;
            if (delta.TotalSeconds < 0)
            {
                throw new ArgumentOutOfRangeException("时间格式错误.1");
            }
            ticks = (long)delta.TotalSeconds;
        }
        else
        {
            throw new Exception("时间格式错误.2");
        }
        writer.WriteValue(ticks);
    }
}

请注意JsonConverter类中有一个方法叫CanConvert(Type t),那由此我们是否可以用这样的方式来实现呢?如代码所示:

public class ModelEntity
{
    public string value { get; set; }

    [JsonConverter(typeof(UnixDateTimeConverter))]
    public DateTime createtime { get; set; }
}
 
OK,debug走起,
private void button1_Click(object sender, EventArgs e)
{
    var model = new ModelEntity();
    model.birthdate = DateTime.Now;
    model.value = "Find a Way";
    var str = Common.SerializerHelper<ModelEntity>.JsonSerialize(model);
 }

image

那我修改实体,如下:

image

再去反序列化呢?

image

时间戳,高大尚,妈妈再也不用担心我写代码.

上面的一大堆,简单的实现的话就下面的一段就可以了:

Newtonsoft.Json转换json,可是如果数据库是日期类型转换出来之后变成了"\/Date(1269582661683+0800)\/"这样的格式

   

   下面是解决方案:

        List<UserInfo> listUser = UserInfoManage.GetUserInfoBySQL("Select Top 5 * From Userinfo");
        IsoDateTimeConverter timeConverter = new IsoDateTimeConverter();
        //这里使用自定义日期格式,如果不使用的话,默认是ISO8601格式     
        timeConverter.DateTimeFormat = "yyyy'-'MM'-'dd' 'HH':'mm':'ss";
        //listUser是准备转换的对象
        string ResJsonStr = JsonConvert.SerializeObject(listUser, Formatting.Indented, timeConverter);
        return ResJsonStr;

 

 [{
    "Id": 6,
    "UserId": "food6",
    "UserPwd": "f0000",
    "State": true,
    "RegTime": "2009-10-16 16:59:59",
    "ComeInt": 1,
    "RegAdmin": "1",
    "IsVip": 0,
    "IsPhoneSale": 0,
    "IsA": 0,
    "IsB": 0,
    "A": "",
    "B": "",
    "C": ""
  }]


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值