C# 带有DateTime成员的反序列化对象不适用于Json.Net

C# 带有DateTime成员的反序列化对象不适用于Json.Net,c#,json.net,C#,Json.net,我正在从webrequest检索JSON,我想将其反序列化为以下类: public class MyData { public int id { get; set; } public DateTime openTime { get; set; } MyData() {} } 这是我从服务器收到的JSON: var json= @"{""Id"": ""12345"",""openTime"":""2015-09-01T12:00:00:000Z""}" 据我所知,这个Dat

我正在从webrequest检索JSON,我想将其反序列化为以下类:

public class MyData
{
   public int id { get; set; }
   public DateTime openTime { get; set; }
   MyData() {}
}
这是我从服务器收到的JSON:

var json= @"{""Id"": ""12345"",""openTime"":""2015-09-01T12:00:00:000Z""}"
据我所知,这个DateTime字符串是ISO 8601,但我不明白为什么在毫秒的末尾有三个0和一个额外的Z。这就是我试图将字符串转换为我的对象的方式:

var responseInstance = JsonConvert.DeserializeObject<MyData>(json,new IsoDateTimeConverter());
var responseInstance=JsonConvert.DeserializeObject(json,新的IsoDateTimeConverter());
这会引发System.FormatException:字符串未被识别为有效的日期时间

当我尝试添加JsonSerializerSetting而不是像这样添加IsoDateTimeConverter时:

var deserializeSetting = new JsonSerializerSettings()
{
   DateFormatHandling = DateFormatHandling.IsoDateFormat
};
var responseInstance = JsonConvert.DeserializeObject<MyData>(json,deserializeSetting);
JsonSerializerSettings settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new BadDateFixingConverter() },
    DateParseHandling = DateParseHandling.None
};

MyData obj = JsonConvert.DeserializeObject<MyData>(json, settings);
       JsonSerializerSettings settings = new JsonSerializerSettings
        {
            Converters = new List<JsonConverter> {new BadDateFixingConverter("yyyyMMddHHmmss") },
            DateParseHandling = DateParseHandling.None
        };
var deserializeSetting=new JsonSerializerSettings()
{
DateFormatHandling=DateFormatHandling.IsoDateFormat
};
var responseInstance=JsonConvert.DeserializeObject(json,deserializeSetting);
不会引发异常,但datetime成员始终显示01.01.0001 00:00:00

var deserializeSetting = new JsonSerializerSettings()
{
    DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("o")
};

这应该行得通,或者试试Libraie,他非常棒。

问题是你的日期字符串格式不正确。秒和毫秒之间应该有一个句点字符(
),而不是冒号(
)。Json.Net在内部使用
DateTime.Parse
解析日期。如果失败,那么它会默默地接受错误,并且永远不会在对象上设置日期。因此,默认日期为01/01/0001 00:00:00

编辑

如果无法更改JSON(例如,因为它由第三方控制),可以使用自定义JSON转换器来正确反序列化错误格式

class BadDateFixingConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(DateTime) || objectType == typeof(DateTime?));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        string rawDate = (string)reader.Value;
        DateTime date;

        // First try to parse the date string as is (in case it is correctly formatted)
        if (DateTime.TryParse(rawDate, out date))
        {
            return date;
        }

        // If not, see if the string matches the known bad format. 
        // If so, replace the ':' with '.' and reparse.
        if (rawDate.Length > 19 && rawDate[19] == ':')
        {
            rawDate = rawDate.Substring(0, 19) + '.' + rawDate.Substring(20);
            if (DateTime.TryParse(rawDate, out date))
            {
                return date;
            }
        }

        // It's not a date after all, so just return the default value
        if (objectType == typeof(DateTime?)) 
            return null;

        return DateTime.MinValue;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
像这样使用它:

var deserializeSetting = new JsonSerializerSettings()
{
   DateFormatHandling = DateFormatHandling.IsoDateFormat
};
var responseInstance = JsonConvert.DeserializeObject<MyData>(json,deserializeSetting);
JsonSerializerSettings settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new BadDateFixingConverter() },
    DateParseHandling = DateParseHandling.None
};

MyData obj = JsonConvert.DeserializeObject<MyData>(json, settings);
       JsonSerializerSettings settings = new JsonSerializerSettings
        {
            Converters = new List<JsonConverter> {new BadDateFixingConverter("yyyyMMddHHmmss") },
            DateParseHandling = DateParseHandling.None
        };
JsonSerializerSettings设置=新的JsonSerializerSettings
{
转换器=新列表{new BadDateFixingConverter()},
DateParseHandling=DateParseHandling.None
};
MyData obj=JsonConvert.DeserializeObject(json,设置);
小提琴:

像这样使用它:

var deserializeSetting = new JsonSerializerSettings()
{
   DateFormatHandling = DateFormatHandling.IsoDateFormat
};
var responseInstance = JsonConvert.DeserializeObject<MyData>(json,deserializeSetting);
JsonSerializerSettings settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new BadDateFixingConverter() },
    DateParseHandling = DateParseHandling.None
};

MyData obj = JsonConvert.DeserializeObject<MyData>(json, settings);
       JsonSerializerSettings settings = new JsonSerializerSettings
        {
            Converters = new List<JsonConverter> {new BadDateFixingConverter("yyyyMMddHHmmss") },
            DateParseHandling = DateParseHandling.None
        };
JsonSerializerSettings设置=新的JsonSerializerSettings
{
转换器=新列表{new BadDateFixingConverter(“yyyyMMddHHmmss”)},
DateParseHandling=DateParseHandling.None
};

我实际使用的是json.Net Newtonsoft。我正在做的那些方法调用是newtonsoftlibriary调用。不幸的是,System.Runtime.Serialization中没有DateTimeFormat。在.NET 4.5及更高版本中有:谢谢,这解决了这个问题。但是,我无法控制从服务器接收到的内容,因此我想知道字符串是错误的,还是使用了错误的格式?字符串是错误的。如果有句号,格式将是正确的;这就是ISO 8601格式,它是一种标准格式(Zulu时区是UTC时间)。你能联系API的提供者让他们修复它吗?如果没有,则可以创建一个JSON转换器来尝试在反序列化过程中修复错误日期。