将 JSON DateTime 值转换为零值的最佳方法(例如“0000-00-00 00:00:00”)

Hei*_*ing 5 c# datetime json.net converters

仅使用零转换 JSON DateTime 值(例如“0000-00-00 00:00:00”)不适用于标准 Json.net IsoDateTimeConverter。我开发了一个自定义转换器来保存该值 DateTime.MinValue。此外,DateTime.MinValue 将被写为“ZeroDateString”。所有其他字符串均由 IsoDateTimeConverter 基类处理。我在 DateTime 属性的 JsonNet 注释上使用此转换器。

是否有更好、更简单的方法来处理这个问题,例如在更基本的级别上,不需要注释?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace DataLayer
{
    /// <summary>
    /// Custom IsoDateTimeConverter for DateTime strings with zeros.
    /// 
    /// Usage Sample
    ///  [JsonConverter(typeof(ZerosIsoDateTimeConverter), "yyyy-MM-dd hh:mm:ss", "0000-00-00 00:00:00")]
    ///  public DateTime Zerodate { get; set; }

    /// </summary>
    public class ZerosIsoDateTimeConverter : Newtonsoft.Json.Converters.IsoDateTimeConverter
    {
        /// <summary>
        /// The string representing a datetime value with zeros. E.g. "0000-00-00 00:00:00"
        /// </summary>
        private readonly string _zeroDateString;

        /// <summary>
        /// Initializes a new instance of the <see cref="ZerosIsoDateTimeConverter"/> class.
        /// </summary>
        /// <param name="dateTimeFormat">The date time format.</param>
        /// <param name="zeroDateString">The zero date string. 
        /// Please be aware that this string should match the date time format.</param>
        public ZerosIsoDateTimeConverter(string dateTimeFormat, string zeroDateString)
        {
            DateTimeFormat = dateTimeFormat;
            _zeroDateString = zeroDateString;
        }

        /// <summary>
        /// Writes the JSON representation of the object.
        /// If a DateTime value is DateTime.MinValue than the zeroDateString will be set as output value.
        /// </summary>
        /// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (value is DateTime && (DateTime) value == DateTime.MinValue)
            {
                value = _zeroDateString;
                serializer.Serialize(writer, value);
            }
            else
            {
                base.WriteJson(writer, value, serializer);
            }
        }

        /// <summary>
        /// Reads the JSON representation of the object.
        /// If  an input value is same a zeroDateString than DateTime.MinValue will be set as return value
        /// </summary>
        /// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="existingValue">The existing value of object being read.</param>
        /// <param name="serializer">The calling serializer.</param>
        /// <returns>
        /// The object value.
        /// </returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
            JsonSerializer serializer)
        {
            return reader.Value.ToString() == _zeroDateString
                ? DateTime.MinValue
                : base.ReadJson(reader, objectType, existingValue, serializer);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

我遇到了同样的问题,我为此使用了自定义转换器......

class MyDateConverter: Newtonsoft.Json.Converters.IsoDateTimeConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.Value != null && reader.Value.ToString().StartsWith("0000")) return null;
        else return base.ReadJson(reader, objectType, existingValue, serializer);
    }
}
Run Code Online (Sandbox Code Playgroud)


Ayb*_*ybe 2

您可以ContractResolver按照文档中的说明使用 a 来执行此操作:

IContractResolver 接口提供了一种自定义 JsonSerializer 如何将 .NET 对象序列化和反序列化为 JSON 的方法,而无需在类上放置属性。任何可以使用属性或方法控制序列化在对象、集合、属性等上设置的内容也可以使用 IContractResolver 进行设置。

http://james.newtonking.com/json/help/index.html?topic=html/ContractResolver.htm

例子:

using System;
using System.Windows.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private string json = @"
{
    ""Date"": ""0000-00-00 00:00:00""
}
";

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var myClass = new MyClass();

            var deserializeObject = JsonConvert.DeserializeObject<MyClass>(json,
                new JsonSerializerSettings {ContractResolver = new CustomDateContractResolver()});

            string serializeObject = JsonConvert.SerializeObject(myClass, Formatting.Indented,
                new JsonSerializerSettings {ContractResolver = new CustomDateContractResolver()});
        }
    }

    internal class MyClass
    {
        public DateTime DateTime { get; set; }
    }

    internal class CustomDateContractResolver : DefaultContractResolver
    {
        protected override JsonContract CreateContract(Type objectType)
        {
            JsonContract contract = base.CreateContract(objectType);
            bool b = objectType == typeof (DateTime);
            if (b)
            {
                contract.Converter = new ZerosIsoDateTimeConverter("yyyy-MM-dd hh:mm:ss", "0000-00-00 00:00:00");
            }
            return contract;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但正如@Jeroen Mostert指出的那样,您应该只使用“常规”行为,以免以后可能遇到麻烦,并且无论您在何处使用日期,都必须遵循此自定义逻辑。