我正在从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.这就是我试图将字符串转换为我的对象:< / p>
var responseInstance = JsonConvert.DeserializeObject<MyData>(json,new IsoDateTimeConverter());
抛出System.FormatException:String未被识别为有效的DateTime。
当我尝试添加JsonSerializerSetting而不是像这样的IsoDateTimeConverter时:
var deserializeSetting = new JsonSerializerSettings()
{
DateFormatHandling = DateFormatHandling.IsoDateFormat
};
var responseInstance = JsonConvert.DeserializeObject<MyData>(json,deserializeSetting);
没有抛出异常,而是datetime成员始终显示01.01.0001 00:00:00
答案 0 :(得分:5)
问题是您的日期字符串格式不正确。在秒和毫秒之间应该有一个句点字符(.
),而不是冒号(:
)。 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();
}
}
像这样使用:
JsonSerializerSettings settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter> { new BadDateFixingConverter() },
DateParseHandling = DateParseHandling.None
};
MyData obj = JsonConvert.DeserializeObject<MyData>(json, settings);
答案 1 :(得分:4)
class BadDateFixingConverter : JsonConverter
{
string FormatStringVaue;
public BadDateFixingConverter(string FormatString)
{
this.FormatStringVaue = FormatString;
}
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;
try
{
return DateTime.ParseExact(rawDate, FormatStringVaue, null);
}
catch
{
// 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();
}
}
像这样使用:
JsonSerializerSettings settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter> {new BadDateFixingConverter("yyyyMMddHHmmss") },
DateParseHandling = DateParseHandling.None
};
答案 2 :(得分:-1)
var deserializeSetting = new JsonSerializerSettings()
{
DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("o")
};
这应该可行,或者尝试Newtonsoft图书馆员,这真是棒极了。