仅使用零(例如“0000-00-00 00:00:00”)转换JSON DateTime值不适用于标准Json.net IsoDateTimeConverter。我开发了一个自定义转换器,保存了这个值DateTime.MinValue。 DateTime.MinValue也将被写为“ZeroDateString”。所有其他字符串由基本IsoDateTimeConverter类处理。 我在JsonNet注释上使用这个转换器来获取DateTime属性。
是否有更好,更简单的方法来解决这个问题,例如:在基本水平,没有需要注释?
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);
}
}
}
答案 0 :(得分:2)
您可以使用ContractResolver
执行此操作,如文档中所述:
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;
}
}
}
但正如 @Jeroen Mostert 指出的那样,您应该使用“常规”行为,以便以后可能不会遇到麻烦,并且无论您何时使用日期,都必须遵循此自定义逻辑。
答案 1 :(得分:1)
我遇到了同样的问题,我为此使用了自定义转换器......
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);
}
}