Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将JSON日期时间值转换为零值的最佳方法(例如“0000-00-00 00:00:00”)_C#_Datetime_Json.net_Converter - Fatal编程技术网

C# 将JSON日期时间值转换为零值的最佳方法(例如“0000-00-00 00:00:00”)

C# 将JSON日期时间值转换为零值的最佳方法(例如“0000-00-00 00:00:00”),c#,datetime,json.net,converter,C#,Datetime,Json.net,Converter,仅使用零(例如“0000-00-00 00 00:00:00”)转换JSON日期时间值不适用于标准的JSON.net IsoDateTimeConverter。我开发了一个自定义转换器来保存这个值DateTime.MinValue。此外,DateTime.MinValue将被写入“ZeroDateString”。所有其他字符串都由基础IsoDateTimeConverter类处理。 我在JsonNet注释上使用这个转换器来表示日期时间属性 是否有更好、更简单的方法来处理此问题,例如在mor基本级

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

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

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);
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Text.RegularExpressions;
使用System.Threading.Tasks;
使用Newtonsoft.Json;
命名空间数据层
{
/// 
///用于带零的日期时间字符串的自定义IsoDateTimeConverter。
/// 
///使用示例
///[JsonConverter(类型为(ZerosIsoDateTimeConverter),“yyyy-MM-dd hh:MM:ss”,“0000-00-00:00:00”)]
///公共日期时间Zerodate{get;set;}
/// 
公共类ZerosIsoDateTimeConverter:Newtonsoft.Json.Converters.IsoDateTimeConverter
{
/// 
///用零表示日期时间值的字符串,例如“0000-00-00:00:00”
/// 
私有只读字符串_zeroDateString;
/// 
///初始化类的新实例。
/// 
///日期时间格式。
///零日期字符串。
///请注意,此字符串应与日期时间格式匹配。
公共ZerosIsoDateTimeConverter(字符串dateTimeFormat,字符串zeroDateString)
{
DateTimeFormat=DateTimeFormat;
_zeroDateString=zeroDateString;
}
/// 
///写入对象的JSON表示形式。
///如果DateTime值为DateTime.MinValue,则zeroDateString将设置为输出值。
/// 
///要写信给的人。
///价值。
///调用序列化程序。
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
if(值为DateTime&&(DateTime)值==DateTime.MinValue)
{
值=_zeroDateString;
serializer.Serialize(writer,value);
}
其他的
{
base.WriteJson(writer、value、serializer);
}
}
/// 
///读取对象的JSON表示形式。
///如果输入值与DateTime相同,则zeroDateString.MinValue将设置为返回值
/// 
///这本书是用来阅读的。
///对象的类型。
///正在读取的对象的现有值。
///调用序列化程序。
/// 
///对象值。
/// 
public override object ReadJson(JsonReader reader,Type objectType,object existingValue,
JsonSerializer(序列化程序)
{
返回reader.Value.ToString()
?DateTime.MinValue
:base.ReadJson(reader、objectType、existingValue、serializer);
}
}
}

您可以使用
ContractResolver
执行此操作,如文档中所述:

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

示例:

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;
        }
    }
}
使用系统;
使用System.Windows.Forms;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Converters;
使用Newtonsoft.Json.Serialization;
命名空间Windows窗体应用程序1
{
公共部分类Form1:Form
{
私有字符串json=@”
{
“日期”:“0000-00-00:00:00”
}
";
公共表格1()
{
初始化组件();
}
私有void Form1\u加载(对象发送方、事件参数e)
{
var myClass=新的myClass();
var deserializeObject=JsonConvert.deserializeObject(json,
新的JsonSerializerSettings{ContractResolver=new CustomDateContractResolver()});
string serializeObject=JsonConvert.serializeObject(myClass,Formatting.Indented,
新的JsonSerializerSettings{ContractResolver=new CustomDateContractResolver()});
}
}
内部类MyClass
{
公共日期时间日期时间{get;set;}
}
内部类CustomDateContractResolver:DefaultContractResolver
{
受保护的重写JsonContract CreateContract(类型objectType)
{
JsonContract contract=base.CreateContract(objectType);
bool b=objectType==typeof(DateTime);
如果(b)
{
合同转换器=新的ZerosIsoDateTimeConverter(“yyyy-MM-dd hh:MM:ss”、“0000-00-00:00:00”);
}
退货合同;
}
}
}


但是正如@Jeroen Mostert所指出的,您应该使用“常规”行为,以避免以后遇到麻烦,并且在使用日期的任何地方都必须遵循此自定义逻辑。

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

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);
    }
}

为什么不在JSON中简单地允许空值并使用
DateTime?
,而不是使用哨兵值?.NET“零日期”是0001-01-01,SQL Server不允许1753-01-01之前的日期,这些内容很快就会变得混乱。将这些值存储为可为空的日期时间值可能是更好的方法。这很容易实现。但是我仍然需要处理传入的“0000…”JSON值使用示例注释中的日期格式可能应该将小时指定为24小时