I have a Nancy JSON REST service that uses the following serialisation code...
FormatterExtensions.AsJson(this.Response, insightManager.CaseSummary(x.caseId));
Which is then deserilised by...
public static T ParseResponseForObject<T>(string response)
{
var javaScriptSerializer = new JavaScriptSerializer();
try
{
return javaScriptSerializer.Deserialize<T>(response);
}
catch (Exception ex)
{
throw new Exception(response, ex);
}
}
And the insightManager.CaseSummary(x.caseId) code returns an instance of a class that contains a nullable DateTime.
The problem is that in the serialisation/deserialistion process the date loses an hour, which I asume is some kind of UTC offset. Which is kind of anoying because I only want the date portion anyway, so it looks like all of dates are the day before they really are.
I've seen plenty of posts bout fixing tis in javascript but I'm not sure how to apply them when both parts of my code are using "standard" serilasers.
So, I found the answer in the end. Essentially I just need to call .ToLocalTime() after the dates are deserialised to ensure I get the results I need. A very good explanation of why here http://www.west-wind.com/weblog/posts/2008/Sep/03/Watch-out-for-Date-Kind-in-JSON-Deserialization
But, in short, when you serialise to JSON dates are always converted into UTC time so the date you get back from a deserialise will always be a UTC date so you need to convert it back to local time.
Just in case anyone else has this problem, I have adapted my ParseResponseForObject<T>
function to always use local time for any DateTime or DateTime?...
public static T ParseResponseForObject<T>(string response)
{
var javaScriptSerializer = new JavaScriptSerializer();
try
{
var obj = javaScriptSerializer.Deserialize<T>(response);
var props = obj
.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var pi in props)
{
if (pi.PropertyType == typeof(DateTime))
{
var origDt = (DateTime)pi.GetValue(obj, null);
pi.SetValue(obj, origDt.ToLocalTime(), null);
}
else if (pi.PropertyType == typeof(DateTime?))
{
var origDt = (DateTime?)pi.GetValue(obj, null);
if (origDt.HasValue)
{
pi.SetValue(obj, origDt.Value.ToLocalTime(), null);
}
}
}
return obj;
}
catch (Exception ex)
{
throw new Exception(response, ex);
}
}