我有一个web api控制器方法,它接受一个复合对象,其中一个属性是DateTime。当我将对象作为XML发布时,一切都很好。如果我把它作为JSON发布,但是,它失败了。
为了获得更多关于为什么它可能失败的信息,我添加了一个自定义日期时间转换器,只是重用Json附带的基本的IsoDateTimeConverter。Net,并通过在转换的值上放置一个断点,我可以看到值转换得很好,但是当它到达模型时,属性被一个新的日期时间填充,而不是我发送的值。发送与XML完全相同的模型可以正常工作。
我对事件的顺序以及它如何从转换为日期时间对象然后在模型绑定时立即丢失有点困惑。我用的是Json。Net isodatetimeeconverter在交互的两端用于序列化和反序列化。
JSON设置:NullValueHandling = NullValueHandling.Ignore,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
Converters = new JsonConverter[]
{
new StringEnumConverter(),
new IsoDateTimeConverter()
}
用于web api端反序列化的自定义转换器(使用IsoDateTimeConverter):
public class CustomDateTimeConverter : DateTimeConverterBase
{
IsoDateTimeConverter isoConverter;
public CustomDateTimeConverter()
{
isoConverter = new IsoDateTimeConverter();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
isoConverter.WriteJson(writer, value, serializer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var returned = isoConverter.ReadJson(reader, objectType, existingValue, serializer);
return returned;
}
}
模型上的日期属性(两端)
public DateTime DateOfBirth { get; set; }
Json格式:
"DateOfBirth":"1980-02-01T00:00:00"
转换器值:
{01/02/1980 00:00:00}
控制器中模型的值:
{01/01/0001 00:00:00}
断点时返回的变量显示了正确的反序列化日期时间,但是之后的模型是一个新的日期时间。
相当困惑,这是如何可以反序列化和决定,它没有直接之后!如有任何帮助,不胜感激。
进一步调查,似乎json绑定器也无法绑定属性-基本字符串属性的负载没有正确绑定,所以这可能是另一个问题的一部分
Json不做日期。将它们作为字符串传递回来,并在客户端脚本中解析它们。
http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx事实证明这与JSON无关- JSON是正确的反序列化,正如我通过覆盖日期转换器发现的那样。问题是对象上有必需的字段,在Web API下需要[DataMember(IsRequired = true)],以便强制执行必需的字段。问题在于对象的其余部分没有使用[DataMember]属性进行装饰,因此它们被忽略了-我假设当模型被绑定时。
function ConvertDateTime(dt) {
var cdt = new Date();
var dateString = dt.substr(6);
var currentTime = new Date(parseInt(dateString));
var month = currentTime.getMonth();
var m = months[month];
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var hr = currentTime.getHours();
var mi = currentTime.getMinutes();
var date = day + "/" + m + "/" + year + " " + hr + ":" + mi;
return date;
}