using System; using System.Text.RegularExpressions; using System.Web.Script.Serialization; using Neo.Afx.Mvc; namespace Neo.Afx.ComponentModel { /// /// Contains JSON extension methods. /// public static partial class Extensions { const string DatePattern = @"\\\/(Date\(-?\d+\))\\\/"; readonly static JavaScriptSerializer Serializer = new JavaScriptSerializer() { MaxJsonLength = Int32.MaxValue, RecursionLimit = 100 }; /// /// Converts the given object to a JSON string. /// /// To avoid circular reference issues, use ScriptIgnore /// attribute on properties that reference a parent instance /// /// /// The object to be converted. /// The serialization options. /// A JSON representation of the object. public static string ToJson(this object data, JsonSerializerOptions options = JsonSerializerOptions.None) { var jsonSerialized = Serializer.Serialize(data); if((options & JsonSerializerOptions.All) == JsonSerializerOptions.All) { if(jsonSerialized.Contains("/Date(")) { jsonSerialized = Regex.Replace(jsonSerialized, DatePattern, new MatchEvaluator(JsonDateConverter)); } //Replace single \ with double \ to escape JSON correctly so it can be parsed by underlying window.JSON.parse() jsonSerialized = jsonSerialized.Replace(@"\", @"\\"); //Replace single \ with double \ to escape JSON correctly so it can be parsed by underlying window.JSON.parse() jsonSerialized = jsonSerialized.Replace("\\\"", "\""); } if((options & JsonSerializerOptions.FormatDateTime) == JsonSerializerOptions.FormatDateTime) { if(jsonSerialized.Contains("/Date(")) { jsonSerialized = Regex.Replace(jsonSerialized, DatePattern, new MatchEvaluator(JsonDateConverter)); } } if((options & JsonSerializerOptions.EscapeBackSlash) == JsonSerializerOptions.EscapeBackSlash) { //Replace single \ with double \ to escape JSON correctly so it can be parsed by underlying window.JSON.parse() jsonSerialized = jsonSerialized.Replace(@"\", @"\\"); } if((options & JsonSerializerOptions.EscapeDoubleSlashQuotes) == JsonSerializerOptions.EscapeDoubleSlashQuotes) { //Replace single \ with double \ to escape JSON correctly so it can be parsed by underlying window.JSON.parse() jsonSerialized = jsonSerialized.Replace("\\\"", "\""); } return jsonSerialized; } /// /// Converts the given JSON string to an object of the given type. /// /// The JSON string to be converted. /// The type of the target object. /// An object of the given type. public static object ParseJson(this string json, Type targetType) { return Serializer.Deserialize(json, targetType); } static string JsonDateConverter(Match regexDateMatch) { var matchDateTicks = regexDateMatch.ToString().Replace(@"\/Date(", "").Replace(@")\/", ""); var dateString = @"""\/Date(" + matchDateTicks + @")\/"""; var date = (DateTime)Serializer.Deserialize(dateString, typeof(DateTime)); date = date.AddMinutes(TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes); return date.ToString(); } } }