Custom JavaScriptConverter for DateTime? Custom JavaScriptConverter for DateTime? ajax ajax

Custom JavaScriptConverter for DateTime?


JavaScriptSerializer can definitely do what you desire.

It's possible to customize the serialization performed by JavaScriptSerializer for any type by creating a custom converter and registering it with the serializer. If you have a class called Person, we could create a converter like so:

public class Person{    public string Name { get; set; }    public DateTime Birthday { get; set; }}public class PersonConverter : JavaScriptConverter{    private const string _dateFormat = "MM/dd/yyyy";    public override IEnumerable<Type> SupportedTypes    {        get        {            return new[] { typeof(Person) };        }    }    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)    {        Person p = new Person();        foreach (string key in dictionary.Keys)        {            switch (key)            {                case "Name":                    p.Name = (string)dictionary[key];                    break;                case "Birthday":                    p.Birthday = DateTime.ParseExact(dictionary[key] as string, _dateFormat, DateTimeFormatInfo.InvariantInfo);                    break;            }        }        return p;    }    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)    {        Person p = (Person)obj;        IDictionary<string, object> serialized = new Dictionary<string, object>();        serialized["Name"] = p.Name;        serialized["Birthday"] = p.Birthday.ToString(_dateFormat);        return serialized;    }}

And use it like this:

JavaScriptSerializer serializer = new JavaScriptSerializer();serializer.RegisterConverters(new[] { new PersonConverter() });Person p = new Person            {                Name = "User Name",                Birthday = DateTime.Now            };string json = serializer.Serialize(p);Console.WriteLine(json);// {"Name":"User Name","Birthday":"12/20/2010"}Person fromJson = serializer.Deserialize<Person>(json);Console.WriteLine(String.Format("{0}, {1}", fromJson.Name, fromJson.Birthday)); // User Name, 12/20/2010 12:00:00 AM


Here's an enhancement for the accepted answer.

Using generics, passing a type and using reflection to determine the datetime properties.

public class ExtendedJavaScriptConverter<T> : JavaScriptConverter where T : new(){    private const string _dateFormat = "dd/MM/yyyy";    public override IEnumerable<Type> SupportedTypes    {        get        {            return new[] { typeof(T) };        }    }    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)    {        T p = new T();        var props = typeof(T).GetProperties();        foreach (string key in dictionary.Keys)        {            var prop = props.Where(t => t.Name == key).FirstOrDefault();            if (prop != null)            {                if (prop.PropertyType == typeof(DateTime))                {                    prop.SetValue(p, DateTime.ParseExact(dictionary[key] as string, _dateFormat, DateTimeFormatInfo.InvariantInfo), null);                }                else                {                    prop.SetValue(p, dictionary[key], null);                }            }        }                          return p;    }          public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)    {        T p = (T)obj;        IDictionary<string, object> serialized = new Dictionary<string, object>();        foreach (PropertyInfo pi in typeof(T).GetProperties())        {            if (pi.PropertyType == typeof(DateTime))            {                serialized[pi.Name] = ((DateTime)pi.GetValue(p, null)).ToString(_dateFormat);            }            else            {                serialized[pi.Name] = pi.GetValue(p, null);            }        }        return serialized;    }    public static JavaScriptSerializer GetSerializer()     {        JavaScriptSerializer serializer = new JavaScriptSerializer();        serializer.RegisterConverters(new[] { new ExtendedJavaScriptConverter<T>() });        return serializer;    }}

Usage is simple:

 JavaScriptSerializer serialiser = ExtendedJavaScriptConverter<Task>.GetSerializer();

Hope that helps someone.


There is actually a nice clean way to do this without knowing the wrapper type or even needing a wrapper object.

You use JavaScriptConverter to convert your object to a Uri that also implements IDictionary. JavaScriptSerializer will serialize this as a string.

This hack is described here: Custom DateTime JSON Format for .NET JavaScriptSerializer