JavaScriptSerializer not deserializing DateTime/TimeSpan Properly

佐手、 提交于 2019-11-28 13:08:36

I found the answer in the following post on GitHub:

https://github.com/NancyFx/Nancy/issues/336

Basically the answer was to create a new TimeSpanJsonConverter that inherits from JavaScriptConverter and then pass that to an instance of your serializer class:

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer()
serializer.RegisterConverters(new[] { new TimeSpanJsonConverter() });

The full class for reference is (written by GrumpyDev):

public class TimeSpanJsonConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new[] { typeof(TimeSpan) };
        }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        return new TimeSpan(
            this.GetValue(dictionary, "days"),
            this.GetValue(dictionary, "hours"),
            this.GetValue(dictionary, "minutes"),
            this.GetValue(dictionary, "seconds"),
            this.GetValue(dictionary, "milliseconds"));
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var timeSpan = (TimeSpan)obj;

        var result = new Dictionary<string, object>
            {
                { "days", timeSpan.Days },
                { "hours", timeSpan.Hours },
                { "minutes", timeSpan.Minutes },
                { "seconds", timeSpan.Seconds },
                { "milliseconds", timeSpan.Milliseconds }
            };

        return result;
    }

    private int GetValue(IDictionary<string, object> dictionary, string key)
    {
        const int DefaultValue = 0;

        object value;
        if (!dictionary.TryGetValue(key, out value))
        {
            return DefaultValue;
        }

        if (value is int)
        {
            return (int)value;
        }

        var valueString = value as string;
        if (valueString == null)
        {
            return DefaultValue;
        }

        int returnValue;
        return !int.TryParse(valueString, out returnValue) ? DefaultValue : returnValue;
    }
}

This will fix your issue if you ever have the same problem.

http://blog.devarchive.net/2008/02/serializing-datetime-values-using.html

All DateTime objects need to be specified explicitly as UTC.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!