using System; using System.Collections.Generic; using DPumpHydr.WinFrmUI.WenSkin.Json.Serialization; using DPumpHydr.WinFrmUI.WenSkin.Json.Utilities; namespace DPumpHydr.WinFrmUI.WenSkin.Json.Converters { /// /// Converts a to and from JSON. /// public class KeyValuePairConverter : JsonConverter { private const string KeyName = "Key"; private const string ValueName = "Value"; private static readonly ThreadSafeStore ReflectionObjectPerType = new ThreadSafeStore(InitializeReflectionObject); private static ReflectionObject InitializeReflectionObject(Type t) { Type[] genericArguments = t.GetGenericArguments(); Type type = ((IList)genericArguments)[0]; Type type2 = ((IList)genericArguments)[1]; return ReflectionObject.Create(t, t.GetConstructor(new Type[2] { type, type2 }), "Key", "Value"); } /// /// Writes the JSON representation of the object. /// /// The to write to. /// The value. /// The calling serializer. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { ReflectionObject reflectionObject = ReflectionObjectPerType.Get(value.GetType()); DefaultContractResolver defaultContractResolver = serializer.ContractResolver as DefaultContractResolver; writer.WriteStartObject(); writer.WritePropertyName((defaultContractResolver != null) ? defaultContractResolver.GetResolvedPropertyName("Key") : "Key"); serializer.Serialize(writer, reflectionObject.GetValue(value, "Key"), reflectionObject.GetType("Key")); writer.WritePropertyName((defaultContractResolver != null) ? defaultContractResolver.GetResolvedPropertyName("Value") : "Value"); serializer.Serialize(writer, reflectionObject.GetValue(value, "Value"), reflectionObject.GetType("Value")); writer.WriteEndObject(); } /// /// Reads the JSON representation of the object. /// /// The to read from. /// Type of the object. /// The existing value of object being read. /// The calling serializer. /// The object value. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { if (!ReflectionUtils.IsNullableType(objectType)) { throw JsonSerializationException.Create(reader, "Cannot convert null value to KeyValuePair."); } return null; } object obj = null; object obj2 = null; reader.ReadAndAssert(); Type key = (ReflectionUtils.IsNullableType(objectType) ? Nullable.GetUnderlyingType(objectType) : objectType); ReflectionObject reflectionObject = ReflectionObjectPerType.Get(key); while (reader.TokenType == JsonToken.PropertyName) { string a = reader.Value.ToString(); if (string.Equals(a, "Key", StringComparison.OrdinalIgnoreCase)) { reader.ReadAndAssert(); obj = serializer.Deserialize(reader, reflectionObject.GetType("Key")); } else if (string.Equals(a, "Value", StringComparison.OrdinalIgnoreCase)) { reader.ReadAndAssert(); obj2 = serializer.Deserialize(reader, reflectionObject.GetType("Value")); } else { reader.Skip(); } reader.ReadAndAssert(); } return reflectionObject.Creator(obj, obj2); } /// /// Determines whether this instance can convert the specified object type. /// /// Type of the object. /// /// true if this instance can convert the specified object type; otherwise, false. /// public override bool CanConvert(Type objectType) { Type type = (ReflectionUtils.IsNullableType(objectType) ? Nullable.GetUnderlyingType(objectType) : objectType); if (type.IsValueType() && type.IsGenericType()) { return type.GetGenericTypeDefinition() == typeof(KeyValuePair<, >); } return false; } } }