JsonSerializerInternalReader
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Utilities;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Globalization;
using System.Linq;
using System.Numerics;
namespace Newtonsoft.Json.Serialization
{
internal class JsonSerializerInternalReader : JsonSerializerInternalBase
{
internal enum PropertyPresence
{
None,
Null,
Value
}
private JsonSerializerProxy _internalSerializer;
public JsonSerializerInternalReader(JsonSerializer serializer)
: base(serializer)
{
}
public void Populate(JsonReader reader, object target)
{
ValidationUtils.ArgumentNotNull(target, "target");
Type type = target.GetType();
JsonContract jsonContract = Serializer._contractResolver.ResolveContract(type);
if (reader.TokenType == JsonToken.None)
reader.Read();
if (reader.TokenType == JsonToken.StartArray) {
if (jsonContract.ContractType != JsonContractType.Array)
throw JsonSerializationException.Create(reader, "Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, type));
JsonArrayContract jsonArrayContract = (JsonArrayContract)jsonContract;
PopulateList(jsonArrayContract.ShouldCreateWrapper ? jsonArrayContract.CreateWrapper(target) : ((IList)target), reader, jsonArrayContract, null, null);
} else {
if (reader.TokenType != JsonToken.StartObject)
throw JsonSerializationException.Create(reader, "Unexpected initial token '{0}' when populating object. Expected JSON object or array.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
CheckedRead(reader);
string id = null;
if (Serializer.MetadataPropertyHandling != MetadataPropertyHandling.Ignore && reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), "$id", StringComparison.Ordinal)) {
CheckedRead(reader);
id = ((reader.Value != null) ? reader.Value.ToString() : null);
CheckedRead(reader);
}
if (jsonContract.ContractType == JsonContractType.Dictionary) {
JsonDictionaryContract jsonDictionaryContract = (JsonDictionaryContract)jsonContract;
PopulateDictionary(jsonDictionaryContract.ShouldCreateWrapper ? jsonDictionaryContract.CreateWrapper(target) : ((IDictionary)target), reader, jsonDictionaryContract, null, id);
} else {
if (jsonContract.ContractType != JsonContractType.Object)
throw JsonSerializationException.Create(reader, "Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, type));
PopulateObject(target, reader, (JsonObjectContract)jsonContract, null, id);
}
}
}
private JsonContract GetContractSafe(Type type)
{
if ((object)type == null)
return null;
return Serializer._contractResolver.ResolveContract(type);
}
public object Deserialize(JsonReader reader, Type objectType, bool checkAdditionalContent)
{
if (reader != null) {
JsonContract contractSafe = GetContractSafe(objectType);
try {
JsonConverter converter = GetConverter(contractSafe, null, null, null);
if (reader.TokenType == JsonToken.None && !ReadForType(reader, contractSafe, converter != null)) {
if (contractSafe != null && !contractSafe.IsNullable)
throw JsonSerializationException.Create(reader, "No JSON content found and type '{0}' is not nullable.".FormatWith(CultureInfo.InvariantCulture, contractSafe.UnderlyingType));
return null;
}
object result = (converter == null || !converter.CanRead) ? CreateValueInternal(reader, objectType, contractSafe, null, null, null, null) : DeserializeConvertable(converter, reader, objectType, null);
if (checkAdditionalContent && reader.Read() && reader.TokenType != JsonToken.Comment)
throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
return result;
} catch (Exception ex) {
if (!IsErrorHandled(null, contractSafe, null, reader as IJsonLineInfo, reader.Path, ex)) {
ClearErrorContext();
throw;
}
HandleError(reader, false, 0);
return null;
}
}
throw new ArgumentNullException("reader");
}
private JsonSerializerProxy GetInternalSerializer()
{
if (_internalSerializer == null)
_internalSerializer = new JsonSerializerProxy(this);
return _internalSerializer;
}
private JToken CreateJToken(JsonReader reader, JsonContract contract)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
if (contract != null) {
if ((object)contract.UnderlyingType == typeof(JRaw))
return JRaw.Create(reader);
if (reader.TokenType == JsonToken.Null && (object)contract.UnderlyingType != typeof(JValue) && (object)contract.UnderlyingType != typeof(JToken))
return null;
}
using (JTokenWriter jTokenWriter = new JTokenWriter()) {
jTokenWriter.WriteToken(reader);
return jTokenWriter.Token;
}
}
private JToken CreateJObject(JsonReader reader)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
using (JTokenWriter jTokenWriter = new JTokenWriter()) {
jTokenWriter.WriteStartObject();
do {
if (reader.TokenType == JsonToken.PropertyName) {
string text = (string)reader.Value;
while (reader.Read() && reader.TokenType == JsonToken.Comment) {
}
if (!CheckPropertyName(reader, text)) {
jTokenWriter.WritePropertyName(text);
jTokenWriter.WriteToken(reader, true, true);
}
} else if (reader.TokenType != JsonToken.Comment) {
jTokenWriter.WriteEndObject();
return jTokenWriter.Token;
}
} while (reader.Read());
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
}
}
private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
{
if (contract != null && contract.ContractType == JsonContractType.Linq)
return CreateJToken(reader, contract);
do {
switch (reader.TokenType) {
case JsonToken.StartObject:
return CreateObject(reader, objectType, contract, member, containerContract, containerMember, existingValue);
case JsonToken.StartArray:
return CreateList(reader, objectType, contract, member, existingValue, null);
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.Boolean:
case JsonToken.Date:
case JsonToken.Bytes:
return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.String: {
string text = (string)reader.Value;
if (string.IsNullOrEmpty(text) && (object)objectType != typeof(string) && (object)objectType != typeof(object) && contract != null && contract.IsNullable)
return null;
if ((object)objectType == typeof(byte[]))
return Convert.FromBase64String(text);
return EnsureType(reader, text, CultureInfo.InvariantCulture, contract, objectType);
}
case JsonToken.StartConstructor: {
string value = reader.Value.ToString();
return EnsureType(reader, value, CultureInfo.InvariantCulture, contract, objectType);
}
case JsonToken.Null:
case JsonToken.Undefined:
return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.Raw:
return new JRaw((string)reader.Value);
default:
throw JsonSerializationException.Create(reader, "Unexpected token while deserializing object: " + reader.TokenType);
case JsonToken.Comment:
break;
}
} while (reader.Read());
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
}
internal string GetExpectedDescription(JsonContract contract)
{
switch (contract.ContractType) {
case JsonContractType.Object:
case JsonContractType.Dictionary:
case JsonContractType.Dynamic:
return "JSON object (e.g. {\"name\":\"value\"})";
case JsonContractType.Array:
return "JSON array (e.g. [1,2,3])";
case JsonContractType.Primitive:
return "JSON primitive value (e.g. string, number, boolean, null)";
case JsonContractType.String:
return "JSON string value";
default:
throw new ArgumentOutOfRangeException();
}
}
private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter, JsonContainerContract containerContract, JsonProperty containerProperty)
{
JsonConverter result = null;
if (memberConverter != null)
result = memberConverter;
else if (containerProperty != null && containerProperty.ItemConverter != null) {
result = containerProperty.ItemConverter;
} else if (containerContract != null && containerContract.ItemConverter != null) {
result = containerContract.ItemConverter;
} else if (contract != null) {
JsonConverter matchingConverter;
if (contract.Converter != null)
result = contract.Converter;
else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null) {
result = matchingConverter;
} else if (contract.InternalConverter != null) {
result = contract.InternalConverter;
}
}
return result;
}
private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
{
Type objectType2 = objectType;
string id;
if (Serializer.MetadataPropertyHandling == MetadataPropertyHandling.Ignore) {
CheckedRead(reader);
id = null;
} else if (Serializer.MetadataPropertyHandling == MetadataPropertyHandling.ReadAhead) {
JTokenReader jTokenReader = reader as JTokenReader;
if (jTokenReader == null) {
JToken jToken = JToken.ReadFrom(reader);
jTokenReader = (JTokenReader)jToken.CreateReader();
jTokenReader.Culture = reader.Culture;
jTokenReader.DateFormatString = reader.DateFormatString;
jTokenReader.DateParseHandling = reader.DateParseHandling;
jTokenReader.DateTimeZoneHandling = reader.DateTimeZoneHandling;
jTokenReader.FloatParseHandling = reader.FloatParseHandling;
jTokenReader.SupportMultipleContent = reader.SupportMultipleContent;
CheckedRead(jTokenReader);
reader = jTokenReader;
}
if (ReadMetadataPropertiesToken(jTokenReader, ref objectType2, ref contract, member, containerContract, containerMember, existingValue, out object newValue, out id))
return newValue;
} else {
CheckedRead(reader);
if (ReadMetadataProperties(reader, ref objectType2, ref contract, member, containerContract, containerMember, existingValue, out object newValue2, out id))
return newValue2;
}
if (HasNoDefinedType(contract))
return CreateJObject(reader);
switch (contract.ContractType) {
case JsonContractType.Object: {
bool createdFromNonDefaultCreator2 = false;
JsonObjectContract jsonObjectContract = (JsonObjectContract)contract;
object obj = (existingValue == null || ((object)objectType2 != objectType && !TypeExtensions.IsAssignableFrom(objectType2, existingValue.GetType()))) ? CreateNewObject(reader, jsonObjectContract, member, containerMember, id, out createdFromNonDefaultCreator2) : existingValue;
if (createdFromNonDefaultCreator2)
return obj;
return PopulateObject(obj, reader, jsonObjectContract, member, id);
}
case JsonContractType.Primitive: {
JsonPrimitiveContract contract3 = (JsonPrimitiveContract)contract;
if (Serializer.MetadataPropertyHandling != MetadataPropertyHandling.Ignore && reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), "$value", StringComparison.Ordinal)) {
CheckedRead(reader);
if (reader.TokenType == JsonToken.StartObject)
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing primitive value: " + reader.TokenType);
object result = CreateValueInternal(reader, objectType2, contract3, member, null, null, existingValue);
CheckedRead(reader);
return result;
}
break;
}
case JsonContractType.Dictionary: {
JsonDictionaryContract jsonDictionaryContract = (JsonDictionaryContract)contract;
if (existingValue != null)
return PopulateDictionary(jsonDictionaryContract.ShouldCreateWrapper ? jsonDictionaryContract.CreateWrapper(existingValue) : ((IDictionary)existingValue), reader, jsonDictionaryContract, member, id);
bool createdFromNonDefaultCreator;
IDictionary dictionary = CreateNewDictionary(reader, jsonDictionaryContract, out createdFromNonDefaultCreator);
if (createdFromNonDefaultCreator) {
if (id != null)
throw JsonSerializationException.Create(reader, "Cannot preserve reference to readonly dictionary, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
if (contract.OnSerializingCallbacks.Count > 0)
throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on readonly dictionary, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
if (contract.OnErrorCallbacks.Count > 0)
throw JsonSerializationException.Create(reader, "Cannot call OnError on readonly list, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
if (!jsonDictionaryContract.HasParametrizedCreator)
throw JsonSerializationException.Create(reader, "Cannot deserialize readonly or fixed size dictionary: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
}
PopulateDictionary(dictionary, reader, jsonDictionaryContract, member, id);
if (createdFromNonDefaultCreator)
return jsonDictionaryContract.ParametrizedCreator(dictionary);
if (dictionary is IWrappedDictionary)
return ((IWrappedDictionary)dictionary).UnderlyingDictionary;
return dictionary;
}
case JsonContractType.Dynamic: {
JsonDynamicContract contract2 = (JsonDynamicContract)contract;
return CreateDynamic(reader, contract2, member, id);
}
}
string format = "Cannot deserialize the current JSON object (e.g. {{\"name\":\"value\"}}) into type '{0}' because the type requires a {1} to deserialize correctly." + Environment.NewLine + "To fix this error either change the JSON to a {1} or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object." + Environment.NewLine;
format = format.FormatWith(CultureInfo.InvariantCulture, objectType2, GetExpectedDescription(contract));
throw JsonSerializationException.Create(reader, format);
}
private bool ReadMetadataPropertiesToken(JTokenReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue, out object newValue, out string id)
{
id = null;
newValue = null;
if (reader.TokenType == JsonToken.StartObject) {
JObject jObject = (JObject)reader.CurrentToken;
JToken jToken = jObject["$ref"];
if (jToken != null) {
if (jToken.Type != JTokenType.String && jToken.Type != JTokenType.Null)
throw JsonSerializationException.Create(jToken, jToken.Path, "JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, "$ref"), null);
JToken parent = jToken.Parent;
JToken jToken2 = null;
if (parent.Next != null)
jToken2 = parent.Next;
else if (parent.Previous != null) {
jToken2 = parent.Previous;
}
string text = (string)jToken;
if (text != null) {
if (jToken2 != null)
throw JsonSerializationException.Create(jToken2, jToken2.Path, "Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, "$ref"), null);
newValue = Serializer.GetReferenceResolver().ResolveReference(this, text);
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader, reader.Path, "Resolved object reference '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, text, newValue.GetType())), null);
reader.Skip();
return true;
}
}
JToken jToken3 = jObject["$type"];
if (jToken3 != null) {
string qualifiedTypeName = (string)jToken3;
JsonReader reader2 = jToken3.CreateReader();
CheckedRead(reader2);
ResolveTypeName(reader2, ref objectType, ref contract, member, containerContract, containerMember, qualifiedTypeName);
JToken jToken4 = jObject["$value"];
if (jToken4 != null) {
while (true) {
CheckedRead(reader);
if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "$value")
break;
CheckedRead(reader);
reader.Skip();
}
return false;
}
}
JToken jToken5 = jObject["$id"];
if (jToken5 != null)
id = (string)jToken5;
JToken jToken6 = jObject["$values"];
if (jToken6 != null) {
JsonReader reader3 = jToken6.CreateReader();
CheckedRead(reader3);
newValue = CreateList(reader3, objectType, contract, member, existingValue, id);
reader.Skip();
return true;
}
}
CheckedRead(reader);
return false;
}
private bool ReadMetadataProperties(JsonReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue, out object newValue, out string id)
{
id = null;
newValue = null;
if (reader.TokenType == JsonToken.PropertyName) {
string text = reader.Value.ToString();
if (text.Length > 0 && text[0] == '$') {
bool flag;
do {
text = reader.Value.ToString();
if (string.Equals(text, "$ref", StringComparison.Ordinal)) {
CheckedRead(reader);
if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null)
throw JsonSerializationException.Create(reader, "JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, "$ref"));
string text2 = (reader.Value != null) ? reader.Value.ToString() : null;
CheckedRead(reader);
if (text2 != null) {
if (reader.TokenType == JsonToken.PropertyName)
throw JsonSerializationException.Create(reader, "Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, "$ref"));
newValue = Serializer.GetReferenceResolver().ResolveReference(this, text2);
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved object reference '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, text2, newValue.GetType())), null);
return true;
}
flag = true;
} else if (string.Equals(text, "$type", StringComparison.Ordinal)) {
CheckedRead(reader);
string qualifiedTypeName = reader.Value.ToString();
ResolveTypeName(reader, ref objectType, ref contract, member, containerContract, containerMember, qualifiedTypeName);
CheckedRead(reader);
flag = true;
} else if (string.Equals(text, "$id", StringComparison.Ordinal)) {
CheckedRead(reader);
id = ((reader.Value != null) ? reader.Value.ToString() : null);
CheckedRead(reader);
flag = true;
} else {
if (string.Equals(text, "$values", StringComparison.Ordinal)) {
CheckedRead(reader);
object obj = CreateList(reader, objectType, contract, member, existingValue, id);
CheckedRead(reader);
newValue = obj;
return true;
}
flag = false;
}
} while (flag && reader.TokenType == JsonToken.PropertyName);
}
}
return false;
}
private void ResolveTypeName(JsonReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, string qualifiedTypeName)
{
if ((member?.TypeNameHandling ?? containerContract?.ItemTypeNameHandling ?? containerMember?.ItemTypeNameHandling ?? Serializer._typeNameHandling) != 0) {
ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out string typeName, out string assemblyName);
Type type;
try {
type = Serializer._binder.BindToType(assemblyName, typeName);
} catch (Exception ex) {
throw JsonSerializationException.Create(reader, "Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
}
if ((object)type == null)
throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved type '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName, type)), null);
if ((object)objectType != null && (object)objectType != typeof(IDynamicMetaObjectProvider) && !TypeExtensions.IsAssignableFrom(objectType, type))
throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, type.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
objectType = type;
contract = GetContractSafe(type);
}
}
private JsonArrayContract EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract)
{
if (contract == null)
throw JsonSerializationException.Create(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
JsonArrayContract jsonArrayContract = contract as JsonArrayContract;
if (jsonArrayContract == null) {
string format = "Cannot deserialize the current JSON array (e.g. [1,2,3]) into type '{0}' because the type requires a {1} to deserialize correctly." + Environment.NewLine + "To fix this error either change the JSON to a {1} or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array." + Environment.NewLine;
format = format.FormatWith(CultureInfo.InvariantCulture, objectType, GetExpectedDescription(contract));
throw JsonSerializationException.Create(reader, format);
}
return jsonArrayContract;
}
private void CheckedRead(JsonReader reader)
{
if (!reader.Read())
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
}
private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string id)
{
if (HasNoDefinedType(contract))
return CreateJToken(reader, contract);
JsonArrayContract jsonArrayContract = EnsureArrayContract(reader, objectType, contract);
if (existingValue != null) {
if (!jsonArrayContract.CanDeserialize)
throw JsonSerializationException.Create(reader, "Cannot populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType));
return PopulateList(jsonArrayContract.ShouldCreateWrapper ? jsonArrayContract.CreateWrapper(existingValue) : ((IList)existingValue), reader, jsonArrayContract, member, id);
}
bool createdFromNonDefaultCreator;
IList list = CreateNewList(reader, jsonArrayContract, out createdFromNonDefaultCreator);
if (createdFromNonDefaultCreator) {
if (id != null)
throw JsonSerializationException.Create(reader, "Cannot preserve reference to array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
if (contract.OnSerializingCallbacks.Count > 0)
throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
if (contract.OnErrorCallbacks.Count > 0)
throw JsonSerializationException.Create(reader, "Cannot call OnError on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
if (!jsonArrayContract.HasParametrizedCreator && !jsonArrayContract.IsArray)
throw JsonSerializationException.Create(reader, "Cannot deserialize readonly or fixed size list: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
}
if (!jsonArrayContract.IsMultidimensionalArray)
PopulateList(list, reader, jsonArrayContract, member, id);
else
PopulateMultidimensionalArray(list, reader, jsonArrayContract, member, id);
if (createdFromNonDefaultCreator) {
if (jsonArrayContract.IsMultidimensionalArray)
list = CollectionUtils.ToMultidimensionalArray(list, jsonArrayContract.CollectionItemType, contract.CreatedType.GetArrayRank());
else {
if (!jsonArrayContract.IsArray)
return jsonArrayContract.ParametrizedCreator(list);
Array array = Array.CreateInstance(jsonArrayContract.CollectionItemType, new int[1] {
list.Count
});
list.CopyTo(array, 0);
list = array;
}
} else if (list is IWrappedCollection) {
return ((IWrappedCollection)list).UnderlyingCollection;
}
return list;
}
private bool HasNoDefinedType(JsonContract contract)
{
if (contract != null && (object)contract.UnderlyingType != typeof(object) && contract.ContractType != JsonContractType.Linq)
return (object)contract.UnderlyingType == typeof(IDynamicMetaObjectProvider);
return true;
}
private object EnsureType(JsonReader reader, object value, CultureInfo culture, JsonContract contract, Type targetType)
{
if ((object)targetType == null)
return value;
Type objectType = ReflectionUtils.GetObjectType(value);
if ((object)objectType != targetType) {
if (value != null || !contract.IsNullable)
try {
if (!contract.IsConvertable)
return ConvertUtils.ConvertOrCast(value, culture, contract.NonNullableUnderlyingType);
JsonPrimitiveContract jsonPrimitiveContract = (JsonPrimitiveContract)contract;
if (contract.IsEnum) {
if (value is string)
return Enum.Parse(contract.NonNullableUnderlyingType, value.ToString(), true);
if (ConvertUtils.IsInteger(jsonPrimitiveContract.TypeCode))
return Enum.ToObject(contract.NonNullableUnderlyingType, value);
}
if (!(value is BigInteger))
return Convert.ChangeType(value, contract.NonNullableUnderlyingType, culture);
return ConvertUtils.FromBigInteger((BigInteger)value, targetType);
} catch (Exception ex) {
throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(value), targetType), ex);
}
return null;
}
return value;
}
private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target)
{
if (CalculatePropertyDetails(property, ref propertyConverter, containerContract, containerProperty, reader, target, out bool useExistingValue, out object currentValue, out JsonContract propertyContract, out bool gottenCurrentValue))
return false;
object obj;
if (propertyConverter != null && propertyConverter.CanRead) {
if (!gottenCurrentValue && target != null && property.Readable)
currentValue = property.ValueProvider.GetValue(target);
obj = DeserializeConvertable(propertyConverter, reader, property.PropertyType, currentValue);
} else
obj = CreateValueInternal(reader, property.PropertyType, propertyContract, property, containerContract, containerProperty, useExistingValue ? currentValue : null);
if ((!useExistingValue || obj != currentValue) && ShouldSetPropertyValue(property, obj)) {
property.ValueProvider.SetValue(target, obj);
if (property.SetIsSpecified != null) {
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "IsSpecified for property '{0}' on {1} set to true.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType)), null);
property.SetIsSpecified(target, true);
}
return true;
}
return useExistingValue;
}
private bool CalculatePropertyDetails(JsonProperty property, ref JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target, out bool useExistingValue, out object currentValue, out JsonContract propertyContract, out bool gottenCurrentValue)
{
currentValue = null;
useExistingValue = false;
propertyContract = null;
gottenCurrentValue = false;
if (property.Ignored)
return true;
JsonToken tokenType = reader.TokenType;
if (property.PropertyContract == null)
property.PropertyContract = GetContractSafe(property.PropertyType);
ObjectCreationHandling valueOrDefault = property.ObjectCreationHandling.GetValueOrDefault(Serializer._objectCreationHandling);
if (valueOrDefault != ObjectCreationHandling.Replace && (tokenType == JsonToken.StartArray || tokenType == JsonToken.StartObject) && property.Readable) {
currentValue = property.ValueProvider.GetValue(target);
gottenCurrentValue = true;
if (currentValue != null) {
propertyContract = GetContractSafe(currentValue.GetType());
useExistingValue = (!propertyContract.IsReadOnlyOrFixedSize && !propertyContract.UnderlyingType.IsValueType());
}
}
if (!property.Writable && !useExistingValue)
return true;
if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && tokenType == JsonToken.Null)
return true;
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) && !HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) && JsonTokenUtils.IsPrimitiveToken(tokenType) && MiscellaneousUtils.ValueEquals(reader.Value, property.GetResolvedDefaultValue()))
return true;
if (currentValue == null)
propertyContract = property.PropertyContract;
else {
propertyContract = GetContractSafe(currentValue.GetType());
if (propertyContract != property.PropertyContract)
propertyConverter = GetConverter(propertyContract, property.MemberConverter, containerContract, containerProperty);
}
return false;
}
private void AddReference(JsonReader reader, string id, object value)
{
try {
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Read object reference Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, id, value.GetType())), null);
Serializer.GetReferenceResolver().AddReference(this, id, value);
} catch (Exception ex) {
throw JsonSerializationException.Create(reader, "Error reading object reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, id), ex);
}
}
private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag)
{
return (value & flag) == flag;
}
private bool ShouldSetPropertyValue(JsonProperty property, object value)
{
if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && value == null)
return false;
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) && !HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) && MiscellaneousUtils.ValueEquals(value, property.GetResolvedDefaultValue()))
return false;
if (!property.Writable)
return false;
return true;
}
private IList CreateNewList(JsonReader reader, JsonArrayContract contract, out bool createdFromNonDefaultCreator)
{
if (!contract.CanDeserialize)
throw JsonSerializationException.Create(reader, "Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType));
if (contract.IsReadOnlyOrFixedSize) {
createdFromNonDefaultCreator = true;
IList list = contract.CreateTemporaryCollection();
if (contract.ShouldCreateWrapper)
list = contract.CreateWrapper(list);
return list;
}
if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) {
object obj = contract.DefaultCreator();
if (contract.ShouldCreateWrapper)
obj = contract.CreateWrapper(obj);
createdFromNonDefaultCreator = false;
return (IList)obj;
}
if (contract.HasParametrizedCreator) {
createdFromNonDefaultCreator = true;
return contract.CreateTemporaryCollection();
}
if (!contract.IsInstantiable)
throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
}
private IDictionary CreateNewDictionary(JsonReader reader, JsonDictionaryContract contract, out bool createdFromNonDefaultCreator)
{
if (contract.IsReadOnlyOrFixedSize) {
createdFromNonDefaultCreator = true;
return contract.CreateTemporaryDictionary();
}
if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) {
object obj = contract.DefaultCreator();
if (contract.ShouldCreateWrapper)
obj = contract.CreateWrapper(obj);
createdFromNonDefaultCreator = false;
return (IDictionary)obj;
}
if (contract.HasParametrizedCreator) {
createdFromNonDefaultCreator = true;
return contract.CreateTemporaryDictionary();
}
if (!contract.IsInstantiable)
throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
}
private void OnDeserializing(JsonReader reader, JsonContract contract, object value)
{
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Started deserializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null);
contract.InvokeOnDeserializing(value, Serializer._context);
}
private void OnDeserialized(JsonReader reader, JsonContract contract, object value)
{
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Finished deserializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null);
contract.InvokeOnDeserialized(value, Serializer._context);
}
private object PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id)
{
IWrappedDictionary wrappedDictionary = dictionary as IWrappedDictionary;
object obj = (wrappedDictionary != null) ? wrappedDictionary.UnderlyingDictionary : dictionary;
if (id != null)
AddReference(reader, id, obj);
OnDeserializing(reader, contract, obj);
int depth = reader.Depth;
if (contract.KeyContract == null)
contract.KeyContract = GetContractSafe(contract.DictionaryKeyType);
if (contract.ItemContract == null)
contract.ItemContract = GetContractSafe(contract.DictionaryValueType);
JsonConverter jsonConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty);
PrimitiveTypeCode primitiveTypeCode = (contract.KeyContract is JsonPrimitiveContract) ? ((JsonPrimitiveContract)contract.KeyContract).TypeCode : PrimitiveTypeCode.Empty;
bool flag = false;
do {
switch (reader.TokenType) {
case JsonToken.PropertyName: {
object obj2 = reader.Value;
if (!CheckPropertyName(reader, obj2.ToString()))
try {
try {
DateParseHandling dateParseHandling;
switch (primitiveTypeCode) {
case PrimitiveTypeCode.DateTime:
case PrimitiveTypeCode.DateTimeNullable:
dateParseHandling = DateParseHandling.DateTime;
break;
case PrimitiveTypeCode.DateTimeOffset:
case PrimitiveTypeCode.DateTimeOffsetNullable:
dateParseHandling = DateParseHandling.DateTimeOffset;
break;
default:
dateParseHandling = DateParseHandling.None;
break;
}
obj2 = ((dateParseHandling == DateParseHandling.None || !DateTimeUtils.TryParseDateTime(obj2.ToString(), dateParseHandling, reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out object dt)) ? EnsureType(reader, obj2, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType) : dt);
} catch (Exception ex) {
throw JsonSerializationException.Create(reader, "Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), ex);
}
if (!ReadForType(reader, contract.ItemContract, jsonConverter != null))
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
object obj4 = dictionary[obj2] = ((jsonConverter == null || !jsonConverter.CanRead) ? CreateValueInternal(reader, contract.DictionaryValueType, contract.ItemContract, null, contract, containerProperty, null) : DeserializeConvertable(jsonConverter, reader, contract.DictionaryValueType, null));
} catch (Exception ex2) {
if (!IsErrorHandled(obj, contract, obj2, reader as IJsonLineInfo, reader.Path, ex2))
throw;
HandleError(reader, true, depth);
}
break;
}
case JsonToken.EndObject:
flag = true;
break;
default:
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
case JsonToken.Comment:
break;
}
} while (!flag && reader.Read());
if (!flag)
ThrowUnexpectedEndException(reader, contract, obj, "Unexpected end when deserializing object.");
OnDeserialized(reader, contract, obj);
return obj;
}
private object PopulateMultidimensionalArray(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id)
{
int arrayRank = contract.UnderlyingType.GetArrayRank();
if (id != null)
AddReference(reader, id, list);
OnDeserializing(reader, contract, list);
JsonContract contractSafe = GetContractSafe(contract.CollectionItemType);
JsonConverter converter = GetConverter(contractSafe, null, contract, containerProperty);
int? nullable = null;
Stack<IList> stack = new Stack<IList>();
stack.Push(list);
IList list2 = list;
bool flag = false;
do {
int depth = reader.Depth;
if (stack.Count == arrayRank) {
try {
if (ReadForType(reader, contractSafe, converter != null)) {
switch (reader.TokenType) {
case JsonToken.EndArray:
stack.Pop();
list2 = stack.Peek();
nullable = null;
break;
default: {
object value = (converter == null || !converter.CanRead) ? CreateValueInternal(reader, contract.CollectionItemType, contractSafe, null, contract, containerProperty, null) : DeserializeConvertable(converter, reader, contract.CollectionItemType, null);
list2.Add(value);
break;
}
case JsonToken.Comment:
break;
}
continue;
}
} catch (Exception ex) {
JsonPosition position = reader.GetPosition(depth);
if (!IsErrorHandled(list, contract, position.Position, reader as IJsonLineInfo, reader.Path, ex))
throw;
HandleError(reader, true, depth);
if (nullable.HasValue && nullable == position.Position)
throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex);
nullable = position.Position;
continue;
}
break;
}
if (!reader.Read())
break;
switch (reader.TokenType) {
case JsonToken.StartArray: {
IList list3 = new List<object>();
list2.Add(list3);
stack.Push(list3);
list2 = list3;
break;
}
case JsonToken.EndArray:
stack.Pop();
if (stack.Count > 0)
list2 = stack.Peek();
else
flag = true;
break;
default:
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing multidimensional array: " + reader.TokenType);
case JsonToken.Comment:
break;
}
} while (!flag);
if (!flag)
ThrowUnexpectedEndException(reader, contract, list, "Unexpected end when deserializing array.");
OnDeserialized(reader, contract, list);
return list;
}
private void ThrowUnexpectedEndException(JsonReader reader, JsonContract contract, object currentObject, string message)
{
try {
throw JsonSerializationException.Create(reader, message);
} catch (Exception ex) {
if (!IsErrorHandled(currentObject, contract, null, reader as IJsonLineInfo, reader.Path, ex))
throw;
HandleError(reader, false, 0);
}
}
private object PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id)
{
IWrappedCollection wrappedCollection = list as IWrappedCollection;
object obj = (wrappedCollection != null) ? wrappedCollection.UnderlyingCollection : list;
if (id != null)
AddReference(reader, id, obj);
if (list.IsFixedSize) {
reader.Skip();
return obj;
}
OnDeserializing(reader, contract, obj);
int depth = reader.Depth;
if (contract.ItemContract == null)
contract.ItemContract = GetContractSafe(contract.CollectionItemType);
JsonConverter converter = GetConverter(contract.ItemContract, null, contract, containerProperty);
int? nullable = null;
bool flag = false;
do {
try {
if (ReadForType(reader, contract.ItemContract, converter != null)) {
switch (reader.TokenType) {
case JsonToken.EndArray:
flag = true;
break;
default: {
object value = (converter == null || !converter.CanRead) ? CreateValueInternal(reader, contract.CollectionItemType, contract.ItemContract, null, contract, containerProperty, null) : DeserializeConvertable(converter, reader, contract.CollectionItemType, null);
list.Add(value);
break;
}
case JsonToken.Comment:
break;
}
continue;
}
} catch (Exception ex) {
JsonPosition position = reader.GetPosition(depth);
if (!IsErrorHandled(obj, contract, position.Position, reader as IJsonLineInfo, reader.Path, ex))
throw;
HandleError(reader, true, depth);
if (nullable.HasValue && nullable == position.Position)
throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex);
nullable = position.Position;
continue;
}
break;
} while (!flag);
if (!flag)
ThrowUnexpectedEndException(reader, contract, obj, "Unexpected end when deserializing array.");
OnDeserialized(reader, contract, obj);
return obj;
}
private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, JsonProperty member, string id)
{
if (!contract.IsInstantiable)
throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
if (contract.DefaultCreator == null || (contract.DefaultCreatorNonPublic && Serializer._constructorHandling != ConstructorHandling.AllowNonPublicDefaultConstructor))
throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
IDynamicMetaObjectProvider dynamicMetaObjectProvider = (IDynamicMetaObjectProvider)contract.DefaultCreator();
if (id != null)
AddReference(reader, id, dynamicMetaObjectProvider);
OnDeserializing(reader, contract, dynamicMetaObjectProvider);
int depth = reader.Depth;
bool flag = false;
do {
switch (reader.TokenType) {
case JsonToken.PropertyName: {
string text = reader.Value.ToString();
try {
if (!reader.Read())
throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text));
JsonProperty closestMatchProperty = contract.Properties.GetClosestMatchProperty(text);
if (closestMatchProperty != null && closestMatchProperty.Writable && !closestMatchProperty.Ignored) {
if (closestMatchProperty.PropertyContract == null)
closestMatchProperty.PropertyContract = GetContractSafe(closestMatchProperty.PropertyType);
JsonConverter converter = GetConverter(closestMatchProperty.PropertyContract, closestMatchProperty.MemberConverter, null, null);
if (!SetPropertyValue(closestMatchProperty, converter, null, member, reader, dynamicMetaObjectProvider))
reader.Skip();
} else {
Type type = JsonTokenUtils.IsPrimitiveToken(reader.TokenType) ? reader.ValueType : typeof(IDynamicMetaObjectProvider);
JsonContract contractSafe = GetContractSafe(type);
JsonConverter converter2 = GetConverter(contractSafe, null, null, member);
object value = (converter2 == null || !converter2.CanRead) ? CreateValueInternal(reader, type, contractSafe, null, null, member, null) : DeserializeConvertable(converter2, reader, type, null);
contract.TrySetMember(dynamicMetaObjectProvider, text, value);
}
} catch (Exception ex) {
if (!IsErrorHandled(dynamicMetaObjectProvider, contract, text, reader as IJsonLineInfo, reader.Path, ex))
throw;
HandleError(reader, true, depth);
}
break;
}
case JsonToken.EndObject:
flag = true;
break;
default:
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
}
} while (!flag && reader.Read());
if (!flag)
ThrowUnexpectedEndException(reader, contract, dynamicMetaObjectProvider, "Unexpected end when deserializing object.");
OnDeserialized(reader, contract, dynamicMetaObjectProvider);
return dynamicMetaObjectProvider;
}
private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor<object> creator, string id)
{
ValidationUtils.ArgumentNotNull(creator, "creator");
Dictionary<JsonProperty, PropertyPresence> dictionary = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) ? contract.Properties.ToDictionary((JsonProperty m) => m, (JsonProperty m) => PropertyPresence.None) : null;
Type underlyingType = contract.UnderlyingType;
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) {
string arg = string.Join(", ", (from p in contract.CreatorParameters
select p.PropertyName).ToArray());
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using creator with parameters: {1}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, arg)), null);
}
IDictionary<string, object> extensionData;
IDictionary<JsonProperty, object> dictionary2 = ResolvePropertyAndCreatorValues(contract, containerProperty, reader, underlyingType, out extensionData);
object[] array = new object[contract.CreatorParameters.Count];
IDictionary<JsonProperty, object> dictionary3 = new Dictionary<JsonProperty, object>();
foreach (KeyValuePair<JsonProperty, object> item in dictionary2) {
JsonProperty property = item.Key;
JsonProperty jsonProperty = (!contract.CreatorParameters.Contains(property)) ? contract.CreatorParameters.ForgivingCaseSensitiveFind((JsonProperty p) => p.PropertyName, property.UnderlyingName) : property;
if (jsonProperty != null) {
int num = contract.CreatorParameters.IndexOf(jsonProperty);
array[num] = item.Value;
} else
dictionary3.Add(item);
if (dictionary != null) {
JsonProperty jsonProperty2 = dictionary.Keys.FirstOrDefault((JsonProperty p) => p.PropertyName == property.PropertyName);
if (jsonProperty2 != null)
dictionary[jsonProperty2] = ((item.Value == null) ? PropertyPresence.Null : PropertyPresence.Value);
}
}
object obj = creator(array);
if (id != null)
AddReference(reader, id, obj);
OnDeserializing(reader, contract, obj);
foreach (KeyValuePair<JsonProperty, object> item2 in dictionary3) {
JsonProperty key = item2.Key;
object value = item2.Value;
if (ShouldSetPropertyValue(key, value))
key.ValueProvider.SetValue(obj, value);
else if (!key.Writable && value != null) {
JsonContract jsonContract = Serializer._contractResolver.ResolveContract(key.PropertyType);
if (jsonContract.ContractType == JsonContractType.Array) {
JsonArrayContract jsonArrayContract = (JsonArrayContract)jsonContract;
object value2 = key.ValueProvider.GetValue(obj);
if (value2 != null) {
IWrappedCollection wrappedCollection = jsonArrayContract.CreateWrapper(value2);
IWrappedCollection wrappedCollection2 = jsonArrayContract.CreateWrapper(value);
foreach (object item3 in wrappedCollection2) {
wrappedCollection.Add(item3);
}
}
} else if (jsonContract.ContractType == JsonContractType.Dictionary) {
JsonDictionaryContract jsonDictionaryContract = (JsonDictionaryContract)jsonContract;
object value3 = key.ValueProvider.GetValue(obj);
if (value3 != null) {
IDictionary dictionary4 = jsonDictionaryContract.ShouldCreateWrapper ? jsonDictionaryContract.CreateWrapper(value3) : ((IDictionary)value3);
IDictionary dictionary5 = jsonDictionaryContract.ShouldCreateWrapper ? jsonDictionaryContract.CreateWrapper(value) : ((IDictionary)value);
IDictionaryEnumerator enumerator4 = dictionary5.GetEnumerator();
try {
while (enumerator4.MoveNext()) {
DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator4.Current;
dictionary4.Add(dictionaryEntry.Key, dictionaryEntry.Value);
}
} finally {
(enumerator4 as IDisposable)?.Dispose();
}
}
}
}
}
if (extensionData != null) {
foreach (KeyValuePair<string, object> item4 in extensionData) {
contract.ExtensionDataSetter(obj, item4.Key, item4.Value);
}
}
EndObject(obj, reader, contract, reader.Depth, dictionary);
OnDeserialized(reader, contract, obj);
return obj;
}
private object DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, object existingValue)
{
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Started deserializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, objectType, converter.GetType())), null);
object result = converter.ReadJson(reader, objectType, existingValue, GetInternalSerializer());
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Finished deserializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, objectType, converter.GetType())), null);
return result;
}
private IDictionary<JsonProperty, object> ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType, out IDictionary<string, object> extensionData)
{
extensionData = ((contract.ExtensionDataSetter != null) ? new Dictionary<string, object>() : null);
IDictionary<JsonProperty, object> dictionary = new Dictionary<JsonProperty, object>();
bool flag = false;
do {
switch (reader.TokenType) {
case JsonToken.PropertyName: {
string text = reader.Value.ToString();
JsonProperty jsonProperty = contract.CreatorParameters.GetClosestMatchProperty(text) ?? contract.Properties.GetClosestMatchProperty(text);
if (jsonProperty != null) {
if (jsonProperty.PropertyContract == null)
jsonProperty.PropertyContract = GetContractSafe(jsonProperty.PropertyType);
JsonConverter converter = GetConverter(jsonProperty.PropertyContract, jsonProperty.MemberConverter, contract, containerProperty);
if (!ReadForType(reader, jsonProperty.PropertyContract, converter != null))
throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text));
if (!jsonProperty.Ignored) {
if (jsonProperty.PropertyContract == null)
jsonProperty.PropertyContract = GetContractSafe(jsonProperty.PropertyType);
object obj2 = dictionary[jsonProperty] = ((converter == null || !converter.CanRead) ? CreateValueInternal(reader, jsonProperty.PropertyType, jsonProperty.PropertyContract, jsonProperty, contract, containerProperty, null) : DeserializeConvertable(converter, reader, jsonProperty.PropertyType, null));
break;
}
} else {
if (!reader.Read())
throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text));
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}.".FormatWith(CultureInfo.InvariantCulture, text, contract.UnderlyingType)), null);
if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, text, objectType.get_Name()));
}
if (extensionData != null) {
object value = CreateValueInternal(reader, null, null, null, contract, containerProperty, null);
extensionData[text] = value;
} else
reader.Skip();
break;
}
case JsonToken.EndObject:
flag = true;
break;
default:
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
case JsonToken.Comment:
break;
}
} while (!flag && reader.Read());
return dictionary;
}
private bool ReadForType(JsonReader reader, JsonContract contract, bool hasConverter)
{
if (hasConverter)
return reader.Read();
switch (contract?.InternalReadType ?? ReadType.Read) {
case ReadType.Read:
do {
if (!reader.Read())
return false;
} while (reader.TokenType == JsonToken.Comment);
return true;
case ReadType.ReadAsInt32:
reader.ReadAsInt32();
break;
case ReadType.ReadAsDecimal:
reader.ReadAsDecimal();
break;
case ReadType.ReadAsBytes:
reader.ReadAsBytes();
break;
case ReadType.ReadAsString:
reader.ReadAsString();
break;
case ReadType.ReadAsDateTime:
reader.ReadAsDateTime();
break;
case ReadType.ReadAsDateTimeOffset:
reader.ReadAsDateTimeOffset();
break;
default:
throw new ArgumentOutOfRangeException();
}
return reader.TokenType != JsonToken.None;
}
public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, string id, out bool createdFromNonDefaultCreator)
{
object obj = null;
if (objectContract.OverrideCreator != null) {
if (objectContract.CreatorParameters.Count > 0) {
createdFromNonDefaultCreator = true;
return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.OverrideCreator, id);
}
obj = objectContract.OverrideCreator();
} else if (objectContract.DefaultCreator != null && (!objectContract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedCreator == null)) {
obj = objectContract.DefaultCreator();
} else if (objectContract.ParametrizedCreator != null) {
createdFromNonDefaultCreator = true;
return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.ParametrizedCreator, id);
}
if (obj == null) {
if (!objectContract.IsInstantiable)
throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType));
throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType));
}
createdFromNonDefaultCreator = false;
return obj;
}
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id)
{
OnDeserializing(reader, contract, newObject);
Dictionary<JsonProperty, PropertyPresence> dictionary = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) ? contract.Properties.ToDictionary((JsonProperty m) => m, (JsonProperty m) => PropertyPresence.None) : null;
if (id != null)
AddReference(reader, id, newObject);
int depth = reader.Depth;
bool flag = false;
do {
switch (reader.TokenType) {
case JsonToken.PropertyName: {
string text = reader.Value.ToString();
if (!CheckPropertyName(reader, text))
try {
JsonProperty closestMatchProperty = contract.Properties.GetClosestMatchProperty(text);
if (closestMatchProperty == null) {
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}".FormatWith(CultureInfo.InvariantCulture, text, contract.UnderlyingType)), null);
if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, text, contract.UnderlyingType.get_Name()));
if (reader.Read())
SetExtensionData(contract, member, reader, text, newObject);
} else {
if (closestMatchProperty.PropertyContract == null)
closestMatchProperty.PropertyContract = GetContractSafe(closestMatchProperty.PropertyType);
JsonConverter converter = GetConverter(closestMatchProperty.PropertyContract, closestMatchProperty.MemberConverter, contract, member);
if (!ReadForType(reader, closestMatchProperty.PropertyContract, converter != null))
throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text));
SetPropertyPresence(reader, closestMatchProperty, dictionary);
if (!SetPropertyValue(closestMatchProperty, converter, contract, member, reader, newObject))
SetExtensionData(contract, member, reader, text, newObject);
}
} catch (Exception ex) {
if (!IsErrorHandled(newObject, contract, text, reader as IJsonLineInfo, reader.Path, ex))
throw;
HandleError(reader, true, depth);
}
break;
}
case JsonToken.EndObject:
flag = true;
break;
default:
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
case JsonToken.Comment:
break;
}
} while (!flag && reader.Read());
if (!flag)
ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object.");
EndObject(newObject, reader, contract, depth, dictionary);
OnDeserialized(reader, contract, newObject);
return newObject;
}
private bool CheckPropertyName(JsonReader reader, string memberName)
{
if (Serializer.MetadataPropertyHandling == MetadataPropertyHandling.ReadAhead) {
switch (memberName) {
case "$id":
case "$ref":
case "$type":
case "$values":
reader.Skip();
return true;
}
}
return false;
}
private void SetExtensionData(JsonObjectContract contract, JsonProperty member, JsonReader reader, string memberName, object o)
{
if (contract.ExtensionDataSetter != null)
try {
object value = CreateValueInternal(reader, null, null, null, contract, member, null);
contract.ExtensionDataSetter(o, memberName, value);
} catch (Exception ex) {
throw JsonSerializationException.Create(reader, "Error setting value in extension data for type '{0}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType), ex);
}
else
reader.Skip();
}
private void EndObject(object newObject, JsonReader reader, JsonObjectContract contract, int initialDepth, Dictionary<JsonProperty, PropertyPresence> propertiesPresence)
{
if (propertiesPresence != null) {
foreach (KeyValuePair<JsonProperty, PropertyPresence> item in propertiesPresence) {
JsonProperty key = item.Key;
PropertyPresence value = item.Value;
if (value == PropertyPresence.None || value == PropertyPresence.Null)
try {
Required required = key._required ?? contract.ItemRequired ?? Required.Default;
switch (value) {
case PropertyPresence.None:
if (required == Required.AllowNull || required == Required.Always)
throw JsonSerializationException.Create(reader, "Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, key.PropertyName));
if (key.PropertyContract == null)
key.PropertyContract = GetContractSafe(key.PropertyType);
if (HasFlag(key.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) && key.Writable && !key.Ignored)
key.ValueProvider.SetValue(newObject, EnsureType(reader, key.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, key.PropertyContract, key.PropertyType));
break;
case PropertyPresence.Null:
if (required == Required.Always)
throw JsonSerializationException.Create(reader, "Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, key.PropertyName));
break;
}
} catch (Exception ex) {
if (!IsErrorHandled(newObject, contract, key.PropertyName, reader as IJsonLineInfo, reader.Path, ex))
throw;
HandleError(reader, true, initialDepth);
}
}
}
}
private void SetPropertyPresence(JsonReader reader, JsonProperty property, Dictionary<JsonProperty, PropertyPresence> requiredProperties)
{
if (property != null && requiredProperties != null)
requiredProperties[property] = ((reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.Undefined) ? PropertyPresence.Null : PropertyPresence.Value);
}
private void HandleError(JsonReader reader, bool readPastError, int initialDepth)
{
ClearErrorContext();
if (readPastError) {
reader.Skip();
while (reader.Depth > initialDepth + 1 && reader.Read()) {
}
}
}
}
}