Commits

Anonymous committed de9c35f

Completed implementation for DateTime formatting options and made public.

Comments (0)

Files changed (12)

 Json/bin/
 Json/obj/
 _ReSharper.Json/
+Json.5.1.ReSharper.user

Json.Serialization/Enumerations/DateTimeSerializationFormat.cs

 
 namespace Manatee.Json.Serialization.Enumerations
 {
-	internal enum DateTimeSerializationFormat
+	/// <summary>
+	/// Available formatting options for serializing DateTime objects.
+	/// </summary>
+	public enum DateTimeSerializationFormat
 	{
 		/// <summary>
 		/// Output conforms to ISO 8601 formatting: YYYY-MM-DDThh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45+01:00)

Json.Serialization/JsonSerializationTypeRegistry.cs

 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Reflection;
-using System.Text;
+using Manatee.Json.Serialization.Enumerations;
 using Manatee.Json.Serialization.Exceptions;
 
 namespace Manatee.Json.Serialization
 		private static readonly Dictionary<Type, Delegate> ToJsonConverters;
 		private static readonly Dictionary<Type, Delegate> FromJsonConverters;
 		private static readonly JsonSerializer _serializer;
+		private static readonly object lockHolder = new object();
 
-		internal static ToJsonDelegate<T> GetToJsonConverter<T>()
-		{
-			var type = typeof (T);
-			return ToJsonConverters.ContainsKey(type) ? (ToJsonDelegate<T>)ToJsonConverters[type] : null;
-		}
-		internal static FromJsonDelegate<T> GetFromJsonConverter<T>()
-		{
-			var type = typeof(T);
-			return FromJsonConverters.ContainsKey(type) ? (FromJsonDelegate<T>)FromJsonConverters[type] : null;
-		}
+		private static JsonSerializerOptions requestedOptions;
 
 		static JsonSerializationTypeRegistry()
 		{
 			_serializer = new JsonSerializer();
 			RegisterLocalTypes();
 		}
+
+		internal static bool TryEncode<T>(this JsonSerializer serializer, T obj, out JsonValue json)
+		{
+			var converter = GetToJsonConverter<T>();
+			if (converter == null)
+			{
+				json = null;
+				return false;
+			}
+			lock (lockHolder)
+			{
+				requestedOptions = serializer.Options;
+				json = converter(obj);
+				requestedOptions = null;
+				return true;
+			}
+		}
+		internal static bool TryDecode<T>(this JsonSerializer serializer, JsonValue json, out T obj)
+		{
+			var converter = GetFromJsonConverter<T>();
+			if (converter == null)
+			{
+				obj = default(T);
+				return false;
+			}
+			lock (lockHolder)
+			{
+				requestedOptions = serializer.Options;
+				obj = converter(json);
+				requestedOptions = null;
+				return true;
+			}
+		}
+
 		private static void RegisterLocalTypes()
 		{
 			RegisterType(EncodeDateTime, DecodeDateTime);
 			RegisterType(EncodeTimeSpan, DecodeTimeSpan);
 			RegisterType(EncodeGuid, DecodeGuid);
 		}
+		private static ToJsonDelegate<T> GetToJsonConverter<T>()
+		{
+			var type = typeof (T);
+			return ToJsonConverters.ContainsKey(type) ? (ToJsonDelegate<T>)ToJsonConverters[type] : null;
+		}
+		private static FromJsonDelegate<T> GetFromJsonConverter<T>()
+		{
+			var type = typeof(T);
+			return FromJsonConverters.ContainsKey(type) ? (FromJsonDelegate<T>)FromJsonConverters[type] : null;
+		}
 		#endregion
 
 		#region Registration
 		/// <returns>The JSON representation of the DateTime.</returns>
 		public static JsonValue EncodeDateTime(DateTime dt)
 		{
-			return dt.ToString();
+			if (requestedOptions == null)
+				return dt.ToString();
+			switch (requestedOptions.DateTimeSerializationFormat)
+			{
+				case DateTimeSerializationFormat.JavaConstructor:
+					return string.Format("/Date({0})/", dt.Ticks/TimeSpan.TicksPerMillisecond);
+				case DateTimeSerializationFormat.Milliseconds:
+					return dt.Ticks/TimeSpan.TicksPerMillisecond;
+				default:
+					return dt.ToString("s");
+			}
 		}
 		/// <summary>
 		/// Decodes a DateTime object from its JSON representation.
 		/// <returns>The DateTime object.</returns>
 		public static DateTime DecodeDateTime(JsonValue json)
 		{
-			return json.Type == JsonValueType.String ? DateTime.Parse(json.String) : default(DateTime);
+			if (requestedOptions == null)
+				return DateTime.Parse(json.String);
+			switch (requestedOptions.DateTimeSerializationFormat)
+			{
+				case DateTimeSerializationFormat.JavaConstructor:
+					return new DateTime(long.Parse(json.String.Substring(6, json.String.Length - 8))*TimeSpan.TicksPerMillisecond);
+				case DateTimeSerializationFormat.Milliseconds:
+					return new DateTime((long) json.Number*TimeSpan.TicksPerMillisecond);
+				default:
+					return DateTime.Parse(json.String);
+			}
 		}
 		#endregion
 		#region TimeSpan

Json.Serialization/JsonSerializer.cs

 		private const string TypeKey = "#Type";
 		private const string ValueKey = "#Value";
 
+		/// <summary>
+		/// Gets or sets a set of options for the serializer.
+		/// </summary>
 		public JsonSerializerOptions Options { get; set; }
 
 		#region Public Methods
 			var tryPrimitive = PrimitiveMapper.MapToJson(obj);
 			if (tryPrimitive != JsonValue.Null)
 				return tryPrimitive;
-			var converter = JsonSerializationTypeRegistry.GetToJsonConverter<T>();
-			return converter == null ? AutoSerializeObject(obj) : converter(obj);
+			JsonValue json;
+			return this.TryEncode(obj, out json) ? json : AutoSerializeObject(obj);
+			//var converter = JsonSerializationTypeRegistry.GetToJsonConverter<T>();
+			//return converter == null ? AutoSerializeObject(obj) : converter(obj);
 		}
 		/// <summary>
 		/// Serializes the public static properties of a type to a JSON structure.
 			VerifyOptions();
 			if (typeof(IJsonCompatible).IsAssignableFrom(typeof(T)))
 			{
-				var obj = (T)Activator.CreateInstance(typeof (T));
+				var obj = (T)Activator.CreateInstance(typeof(T));
 				((IJsonCompatible)obj).FromJson(json);
 				return obj;
 			}
 				return default(T);
 			if (PrimitiveMapper.IsPrimitive(typeof(T)))
 				return PrimitiveMapper.MapFromJson<T>(json);
-			var converter = JsonSerializationTypeRegistry.GetFromJsonConverter<T>();
-			return converter == null ? AutoDeserializeObject<T>(json) : converter(json);
+			T ret;
+			return this.TryDecode(json, out ret) ? ret : AutoDeserializeObject<T>(json);
+			//var converter = JsonSerializationTypeRegistry.GetFromJsonConverter<T>();
+			//return converter == null ? AutoDeserializeObject<T>(json) : converter(json);
 		}
 		/// <summary>
 		/// Deserializes a JSON structure to the public static properties of a type.

Json.Serialization/JsonSerializerOptions.cs

 		/// If the JsonSerializationTypeRegistry entry for DateTime has been changed to custom
 		/// methods, this property will have no effect.
 		/// </remarks>
-		internal DateTimeSerializationFormat DateTimeSerializationFormat { get; set; }
+		public DateTimeSerializationFormat DateTimeSerializationFormat { get; set; }
 	}
 }

Json.Serialization/Manatee.Json.Serialization.csproj

     <AssemblyName>Manatee.Json.Serialization</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>

Json.Tests/Serialization/JsonSerializerTest.cs

 
 namespace Manatee.Json.Tests.Serialization
 {
-	/// <summary>
-	///This is a test class for JsonSerializer and is intended
-	///to contain all JsonSerializer Unit Tests
-	///</summary>
-	[TestClass()]
+	[TestClass]
 	public class JsonSerializerTest
 	{
 		private JsonSerializer _serializer = new JsonSerializer();
 
-		#region Additional test attributes
-		// 
-		//You can use the following additional attributes as you write your tests:
-		//
-		//Use ClassInitialize to run code before running the first test in the class
-		//[ClassInitialize()]
-		//public static void MyClassInitialize(TestContext testContext)
-		//{
-		//}
-		//
-		//Use ClassCleanup to run code after all tests in a class have run
-		//[ClassCleanup()]
-		//public static void MyClassCleanup()
-		//{
-		//}
-		//
-		//Use TestInitialize to run code before running each test
-		//[TestInitialize()]
-		//public void MyTestInitialize()
-		//{
-		//}
-		//
-		//Use TestCleanup to run code after each test has run
-		//[TestCleanup()]
-		//public void MyTestCleanup()
-		//{
-		//}
-		//
-		#endregion
-
 		#region Deserialize Tests
 		[TestMethod]
 		public void Deserialize_RegisteredType_Successful()
 			Assert.AreEqual(expected, actual);
 		}
 		[TestMethod]
+		public void Deserialize_DateTimeDefaultOptions_Successful()
+		{
+			JsonValue json = DateTime.Today.ToString("");
+			var expected = DateTime.Today;
+			var actual = _serializer.Deserialize<DateTime>(json);
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void Deserialize_DateTimeJavaFormat_Successful()
+		{
+			_serializer.Options = new JsonSerializerOptions
+			{
+				DateTimeSerializationFormat = DateTimeSerializationFormat.JavaConstructor
+			};
+			JsonValue json = string.Format("/Date({0})/", DateTime.Today.Ticks/TimeSpan.TicksPerMillisecond);
+			var expected = DateTime.Today;
+			var actual = _serializer.Deserialize<DateTime>(json);
+			_serializer.Options = null;
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void Deserialize_DateTimeMilliseconds_Successful()
+		{
+			_serializer.Options = new JsonSerializerOptions
+			{
+				DateTimeSerializationFormat = DateTimeSerializationFormat.Milliseconds
+			};
+			JsonValue json = DateTime.Today.Ticks/TimeSpan.TicksPerMillisecond;
+			var expected = DateTime.Today;
+			var actual = _serializer.Deserialize<DateTime>(json);
+			_serializer.Options = null;
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
 		public void Deserialize_Basic_Successful()
 		{
 			var json = new JsonObject
 			Assert.AreEqual(expected, actual);
 		}
 		[TestMethod]
+		public void Serialize_DateTimeDefaultOptions_Successful()
+		{
+			var obj = DateTime.Today;
+			JsonValue expected = DateTime.Today.ToString("s");
+			var actual = _serializer.Serialize(obj);
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void Serialize_DateTimeJavaFormat_Successful()
+		{
+			_serializer.Options = new JsonSerializerOptions
+			                      	{
+			                      		DateTimeSerializationFormat = DateTimeSerializationFormat.JavaConstructor
+			                      	};
+			var obj = DateTime.Today;
+			JsonValue expected = string.Format("/Date({0})/", DateTime.Today.Ticks / TimeSpan.TicksPerMillisecond);
+			var actual = _serializer.Serialize(obj);
+			_serializer.Options = null;
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
+		public void Serialize_DateTimeMilliseconds_Successful()
+		{
+			_serializer.Options = new JsonSerializerOptions
+			                      	{
+			                      		DateTimeSerializationFormat = DateTimeSerializationFormat.Milliseconds
+			                      	};
+			var obj = DateTime.Today;
+			JsonValue expected = DateTime.Today.Ticks / TimeSpan.TicksPerMillisecond;
+			var actual = _serializer.Serialize(obj);
+			_serializer.Options = null;
+			Assert.AreEqual(expected, actual);
+		}
+		[TestMethod]
 		public void Serialize_Basic_Successful()
 		{
 			var obj = new ObjectWithBasicProps

Json.sln.docstates.suo

Binary file modified.

Json.suo

Binary file modified.

Json/Manatee.Json.csproj

     <AssemblyName>Manatee.Json</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="JsonInput.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <WCFMetadata Include="Service References\" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

Manatee.Json - ReadMe.docx

Binary file added.

README.docx

Binary file removed.