C# Json试图猜测令牌类型,但弄错了

C# Json试图猜测令牌类型,但弄错了,c#,json.net,C#,Json.net,我试图改变Newtonsoft序列化程序处理字符串(如“2017-05-27”)的方式 因此,我创建了一个类来代替DateTime,一个用于该类型的转换器,并希望它就是它 问题是,对于“2017-05-27”,它确实有效。但是,如果出于某种原因,我得到了“2017-05-27T23:50:27:00”,即完整的ISO 8601字符串,JsonReader会假装聪明,并将其视为日期时间而不是字符串 有没有办法改变这种行为 到目前为止,我所做的代码如下: using System; using Sy

我试图改变Newtonsoft序列化程序处理字符串(如“2017-05-27”)的方式

因此,我创建了一个类来代替DateTime,一个用于该类型的转换器,并希望它就是它

问题是,对于“2017-05-27”,它确实有效。但是,如果出于某种原因,我得到了“2017-05-27T23:50:27:00”,即完整的ISO 8601字符串,JsonReader会假装聪明,并将其视为日期时间而不是字符串

有没有办法改变这种行为

到目前为止,我所做的代码如下:

using System;
using System.Text.RegularExpressions;
using Newtonsoft.Json;

namespace ConverterGames
{
    public class MyDate
    {
        public int Year { get; set; }
        public int Month { get; set; }
        public int Day { get; set; }
    }
    public class Xxx
    {
        public MyDate Aaa { get; set; }
    }

    public class DateJsonConverter : JsonConverter
    {
        private readonly Regex _isoDate = new Regex(@"^(\d+)-(\d+)-(\d+).*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            // gives "string" for 2017-04-27 :-)
            // gives DateTime for 2017-04-27T20:00:00.00 :-(
            // I want string only here.
            Console.WriteLine(reader.Value.GetType());

            Match m = _isoDate.Match((string)reader.Value);
            if (!m.Success)
            {
                throw new Exception($"Format error for {(string)reader.Value}");
            }
            return new MyDate
            {
                Year = Int32.Parse(m.Groups[1].Value),
                Month = Int32.Parse(m.Groups[2].Value),
                Day = Int32.Parse(m.Groups[3].Value),
            };
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(MyDate);
        }
    }

    class Program
    {
        static void Main()
        {
            string Data = "{\"aaa\":\"2017-05-12\"}";
            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.Converters.Add(new DateJsonConverter());

            // good
            Xxx x= JsonConvert.DeserializeObject<Xxx>(Data, settings);
            Console.WriteLine(x.Aaa.Year);


            // fails
            Data = "{\"aaa\":\"2017-05-12T08:15:00\"}";
            x = JsonConvert.DeserializeObject<Xxx>(Data, settings);
            Console.WriteLine(x.Aaa.Year);
        }
    }
}
使用系统;
使用System.Text.RegularExpressions;
使用Newtonsoft.Json;
名称空间转换器
{
公共类MyDate
{
公共整数年{get;set;}
公共整数月{get;set;}
公共整数日{get;set;}
}
公共类Xxx
{
公共MyDate Aaa{get;set;}
}
公共类DateJsonConverter:JsonConverter
{
private readonly Regex_isoDate=new Regex(@“^(\d+)-(\d+)-(\d+)*”,RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
//给出2017-04-27的“字符串”:
//给出2017-04-27T20:00:00.00的日期时间:-(
//我这里只需要绳子。
Console.WriteLine(reader.Value.GetType());
Match m=_isoDate.Match((字符串)reader.Value);
如果(!m.Success)
{
抛出新异常({(string)reader.Value}的$“格式错误”);
}
返回新的MyDate
{
Year=Int32.Parse(m.Groups[1].Value),
Month=Int32.Parse(m.Groups[2].Value),
Day=Int32.Parse(m.Groups[3].Value),
};
}
公共覆盖布尔CanConvert(类型objectType)
{
return objectType==typeof(MyDate);
}
}
班级计划
{
静态void Main()
{
字符串数据=“{\“aaa\”:\“2017-05-12\”;
JsonSerializerSettings设置=新建JsonSerializerSettings();
settings.converter.Add(new DateJsonConverter());
//好
Xxx x=JsonConvert.DeserializeObject(数据、设置);
控制台写入线(x.Aaa.年);
//失败
数据=“{\“aaa\”:\“2017-05-12T08:15:00\”;
x=JsonConvert.DeserializeObject(数据、设置);
控制台写入线(x.Aaa.年);
}
}
}

有什么我可以做的吗?

是的。因为您要自己处理日期解析,所以只需在序列化程序设置中将
DateParseHandling
设置为
None

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.DateParseHandling = DateParseHandling.None;
settings.Converters.Add(new DateJsonConverter());

Fiddle:

是。由于您将自己处理日期解析,您只需在序列化程序设置中将
DateParseHandling
设置为
None

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.DateParseHandling = DateParseHandling.None;
settings.Converters.Add(new DateJsonConverter());

Fiddle:

好的,明白了。将DateParseHandling设置为none只会强制解析进入解析器而不是词法分析器,然后我的转换器就有机会正确处理它。谢谢!好的,明白了。将DateParseHandling设置为none只会强制解析进入解析器而不是词法分析器,然后我的转换器就有机会处理i不对,谢谢!