using System; using System.Collections.Generic; using System.Text; using System.IO; using Newtonsoft.Json; namespace jMVCHelper { /// /// Utility class for serializing an object to JSON format using a single, shared JsonSerializer object /// into which you can register JsonConverters /// internal class JsonSerializationHelper { private JsonSerializer m_Serializer; public JsonSerializationHelper() { m_Serializer = new JsonSerializer(); m_Serializer.Converters.Add(new DateTimeUTCConverter()); } public void RegisterJsonConverter(JsonConverter converter) { m_Serializer.Converters.Add(converter); } public void WriteSerialized(object obj, TextWriter writer) { if (obj == null) writer.Write("null"); else m_Serializer.Serialize(writer, obj); } public string Serialize(object obj) { if (obj == null) return null; else { StringWriter sw = new StringWriter(); m_Serializer.Serialize(sw, obj); return sw.ToString(); } } public object Deserialize(JsonReader reader, Type type) { if (type != null) return m_Serializer.Deserialize(reader, type); else return m_Serializer.Deserialize(reader); } public object Deserialize(string json, Type type) { if (string.IsNullOrEmpty(json)) return null; else { if (type == null) throw new ArgumentNullException("type"); JsonReader reader = new JsonReader(new System.IO.StringReader(json)); if (typeof(JavaScriptObject).IsAssignableFrom(type)) // Don't specify a type if it's really a JS object, otherwise Json.net throws errors return m_Serializer.Deserialize(reader); else return m_Serializer.Deserialize(reader, type); } } /// /// To avoid timezone problems, dates will be represented in UTC in Javascript /// private class DateTimeUTCConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value) { writer.WriteValue(((DateTime)value).ToUniversalTime()); } public override object ReadJson(JsonReader reader, Type objectType) { if (reader.Value is string) return DateTime.Parse((string)reader.Value); else if (reader.Value is DateTime) return new DateTime(((DateTime)reader.Value).Ticks, DateTimeKind.Utc); else throw new NotImplementedException("DateTimeUTCConverter can't deserialize value of type " + reader.ValueType.FullName); } public override bool CanConvert(Type objectType) { return typeof(DateTime).IsAssignableFrom(objectType); } } } }