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