protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(JsonObjectContract contract) { IList<JsonProperty> properties = base.CreateProperties(contract); properties = properties.Where(p => !notSerilizingProperties.Contains(p.PropertyName) ).ToList(); return properties; }
// Token: 0x06000BDB RID: 3035 // RVA: 0x00046004 File Offset: 0x00044204 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 this.CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.OverrideCreator, id); } obj = objectContract.OverrideCreator(new object[0]); } else if (objectContract.DefaultCreator != null && (!objectContract.DefaultCreatorNonPublic || this.Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedCreator == null)) { obj = objectContract.DefaultCreator(); } else if (objectContract.ParametrizedCreator != null) { createdFromNonDefaultCreator = true; return this.CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.ParametrizedCreator, id); } if (obj != null) { createdFromNonDefaultCreator = false; return obj; } if (!objectContract.IsInstantiable) { throw JsonSerializationException.Create(reader, StringUtils.FormatWith("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.", CultureInfo.InvariantCulture, objectContract.UnderlyingType)); } throw JsonSerializationException.Create(reader, StringUtils.FormatWith("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.", CultureInfo.InvariantCulture, objectContract.UnderlyingType)); }
protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(JsonObjectContract contract) { IList<JsonProperty> properties = base.CreateProperties(contract); if(contract.UnderlyingType != typeof(MonoReports.Model.Thickness)) properties = properties.Where(p =>!notSerilizingProperties.Contains(p.PropertyName) ).ToList(); return properties; }
public ModelFilterContext( Type systemType, JsonObjectContract jsonObjectContract, ISchemaRegistry schemaRegistry) { SystemType = systemType; JsonObjectContract = jsonObjectContract; SchemaRegistry = schemaRegistry; }
protected override IList<JsonProperty> CreateProperties(JsonObjectContract contract) { IList<JsonProperty> properties = base.CreateProperties(contract); // only serializer properties that start with the specified character properties = properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList(); return properties; }
protected override IList<JsonProperty> CreateProperties(JsonObjectContract contract) { var properties = base.CreateProperties(contract); foreach (var property in properties) { property.PropertyName = PascalCaseToElement(property.PropertyName); } var result = properties; return result; }
private void SortUnsortedProperties(JsonObjectContract objContract) { if (objContract != null) { var order = 1; foreach (var property in objContract.Properties.Where(each => (each.Order == null) || (each.Order > 0))) { if (property.PropertyName == "name" || property.PropertyName == "#name") { property.Order = -50; } else { property.Order = order++; } } } }
public JsonObjectContract ModifyContract(JsonObjectContract contract) { foreach (var property in contract.Properties) { foreach (var type in property.PropertyType.GetInterfaces().Union(new Type[] { property.PropertyType })) { if (type.IsGenericType) { if (type.GetGenericTypeDefinition() == typeof(NestedList<>)) { property.PropertyName = property.PropertyName + "$$nested"; } } } } return contract; }
public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, string id, out bool createdFromNonDefaultCreator) { object newObject = null; if (objectContract.OverrideCreator != null) { if (objectContract.CreatorParameters.Count > 0) { createdFromNonDefaultCreator = true; return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.OverrideCreator, id); } newObject = objectContract.OverrideCreator(new object[0]); } else if (objectContract.DefaultCreator != null && (!objectContract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedCreator == null)) { // use the default constructor if it is... // public // non-public and the user has change constructor handling settings // non-public and there is no other creator newObject = objectContract.DefaultCreator(); } else if (objectContract.ParametrizedCreator != null) { createdFromNonDefaultCreator = true; return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.ParametrizedCreator, id); } if (newObject == 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 newObject; }
private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType) { IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>(); bool exit = false; do { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); // attempt exact case match first // then try match ignoring case JsonProperty property = contract.ConstructorParameters.GetClosestMatchProperty(memberName) ?? contract.Properties.GetClosestMatchProperty(memberName); if (property != null) { if (property.PropertyContract == null) property.PropertyContract = GetContractSafe(property.PropertyType); JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, containerProperty); if (!ReadForType(reader, property.PropertyContract, propertyConverter != null)) throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); if (!property.Ignored) { if (property.PropertyContract == null) property.PropertyContract = GetContractSafe(property.PropertyType); object propertyValue; if (propertyConverter != null && propertyConverter.CanRead) propertyValue = DeserializeConvertable(propertyConverter, reader, property.PropertyType, null); else propertyValue = CreateValueInternal(reader, property.PropertyType, property.PropertyContract, property, contract, containerProperty, null); propertyValues[property] = propertyValue; } else { reader.Skip(); } } else { if (!reader.Read()) throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); 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, memberName, 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, memberName, objectType.Name)); reader.Skip(); } break; case JsonToken.Comment: break; case JsonToken.EndObject: exit = true; break; default: throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); } } while (!exit && reader.Read()); return propertyValues; }
private void GenerateObjectSchema(Type type, JsonObjectContract contract) { CurrentSchema.Properties = new Dictionary<string, JsonSchema>(); foreach (JsonProperty property in contract.Properties) { if (!property.Ignored) { bool optional = property.NullValueHandling == NullValueHandling.Ignore || HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) || property.ShouldSerialize != null || property.GetIsSpecified != null; JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, !optional); if (property.DefaultValue != null) propertySchema.Default = JToken.FromObject(property.DefaultValue); CurrentSchema.Properties.Add(property.PropertyName, propertySchema); } } if (type.IsSealed) CurrentSchema.AllowAdditionalProperties = false; }
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id) { contract.InvokeOnDeserializing(newObject, base.Serializer.Context); Dictionary <JsonProperty, PropertyPresence> dictionary = contract.Properties.ToDictionary((JsonProperty m) => m, (JsonProperty m) => PropertyPresence.None); if (id != null) { base.Serializer.ReferenceResolver.AddReference(this, id, newObject); } int depth = reader.Depth; do { switch (reader.TokenType) { case JsonToken.PropertyName: { string text = reader.Value.ToString(); try { JsonProperty key = contract.Properties.GetClosestMatchProperty(text); if (key == null) { if (base.Serializer.MissingMemberHandling == MissingMemberHandling.Error) { throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, text, contract.UnderlyingType.Name)); } reader.Skip(); } else { if (!ReadForType(reader, key.PropertyType, key.Converter)) { throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text)); } SetPropertyPresence(reader, key, dictionary); SetPropertyValue(key, reader, newObject); } } catch (Exception ex) { if (IsErrorHandled(newObject, contract, text, ex)) { HandleError(reader, depth); break; } throw; } break; } case JsonToken.EndObject: foreach (KeyValuePair <JsonProperty, PropertyPresence> item in dictionary) { JsonProperty key = item.Key; switch (item.Value) { case PropertyPresence.None: if (key.Required == Required.AllowNull || key.Required == Required.Always) { throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, key.PropertyName)); } if (HasFlag(key.DefaultValueHandling.GetValueOrDefault(base.Serializer.DefaultValueHandling), DefaultValueHandling.Populate) && key.Writable) { key.ValueProvider.SetValue(newObject, EnsureType(key.DefaultValue, CultureInfo.InvariantCulture, key.PropertyType)); } break; case PropertyPresence.Null: if (key.Required == Required.Always) { throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, key.PropertyName)); } break; } } contract.InvokeOnDeserialized(newObject, base.Serializer.Context); return(newObject); default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); case JsonToken.Comment: break; } }while (reader.Read()); throw new JsonSerializationException("Unexpected end when deserializing object."); }
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, string id) { Type objectType = contract.UnderlyingType; if (contract.ParametrizedConstructor == null) throw new JsonSerializationException("Unable to find a constructor to use for type {0}. A class should either have a default constructor or only one constructor with arguments.".FormatWith(CultureInfo.InvariantCulture, objectType)); // create a dictionary to put retrieved values into IDictionary<JsonProperty, object> propertyValues = contract.Properties.Where(p => !p.Ignored).ToDictionary(kv => kv, kv => (object)null); bool exit = false; do { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); if (!reader.Read()) throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); // attempt exact case match first // then try match ignoring case JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); if (property != null) { if (!property.Ignored) propertyValues[property] = CreateValueProperty(reader, property, null, true, null); else reader.Skip(); } else { if (Serializer.MissingMemberHandling == MissingMemberHandling.Error) throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name)); reader.Skip(); } break; case JsonToken.EndObject: exit = true; break; default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); } } while (!exit && reader.Read()); IDictionary<ParameterInfo, object> constructorParameters = contract.ParametrizedConstructor.GetParameters().ToDictionary(p => p, p => (object)null); IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>(); foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues) { ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key; if (matchingConstructorParameter != null) constructorParameters[matchingConstructorParameter] = propertyValue.Value; else remainingPropertyValues.Add(propertyValue); } object createdObject = contract.ParametrizedConstructor.Invoke(constructorParameters.Values.ToArray()); if (id != null) Serializer.ReferenceResolver.AddReference(id, createdObject); contract.InvokeOnDeserializing(createdObject, Serializer.Context); // go through unused values and set the newly created object's properties foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues) { JsonProperty property = remainingPropertyValue.Key; object value = remainingPropertyValue.Value; if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) property.ValueProvider.SetValue(createdObject, value); } contract.InvokeOnDeserialized(createdObject, Serializer.Context); return createdObject; }
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContract collectionValueContract) { contract.InvokeOnSerializing(value, Serializer.Context); SerializeStack.Add(value); writer.WriteStartObject(); bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects); if (isReference) { writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, value)); } if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract)) { WriteTypeProperty(writer, contract.UnderlyingType); } int initialDepth = writer.Top; foreach (JsonProperty property in contract.Properties) { try { if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value)) { object memberValue = property.ValueProvider.GetValue(value); JsonContract memberContract = GetContractSafe(memberValue); WriteMemberInfoProperty(writer, memberValue, property, memberContract); } } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, ex)) HandleError(writer, initialDepth); else throw; } } writer.WriteEndObject(); SerializeStack.RemoveAt(SerializeStack.Count - 1); contract.InvokeOnSerialized(value, Serializer.Context); }
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id) { ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); Type objectType = contract.UnderlyingType; IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, reader, objectType); IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object) null); IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>(); foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues) { ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key; if (matchingConstructorParameter != null) constructorParameters[matchingConstructorParameter] = propertyValue.Value; else remainingPropertyValues.Add(propertyValue); } object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray()); if (id != null) Serializer.ReferenceResolver.AddReference(this, id, createdObject); contract.InvokeOnDeserializing(createdObject, Serializer.Context); // go through unused values and set the newly created object's properties foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues) { JsonProperty property = remainingPropertyValue.Key; object value = remainingPropertyValue.Value; if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) { property.ValueProvider.SetValue(createdObject, value); } else if (!property.Writable && value != null) { // handle readonly collection/dictionary properties JsonContract propertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType); if (propertyContract.ContractType == JsonContractType.Array) { JsonArrayContract propertyArrayContract = propertyContract as JsonArrayContract; object createdObjectCollection = property.ValueProvider.GetValue(createdObject); if (createdObjectCollection != null) { IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection); IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value); foreach (object newValue in newValues) { createdObjectCollectionWrapper.Add(newValue); } } } else if (propertyContract.ContractType == JsonContractType.Dictionary) { JsonDictionaryContract jsonDictionaryContract = propertyContract as JsonDictionaryContract; object createdObjectDictionary = property.ValueProvider.GetValue(createdObject); if (createdObjectDictionary != null) { IWrappedDictionary createdObjectDictionaryWrapper = jsonDictionaryContract.CreateWrapper(createdObjectDictionary); IWrappedDictionary newValues = jsonDictionaryContract.CreateWrapper(value); foreach (DictionaryEntry newValue in newValues) { createdObjectDictionaryWrapper.Add(newValue.Key, newValue.Value); } } } } } contract.InvokeOnDeserialized(createdObject, Serializer.Context); return createdObject; }
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { contract.InvokeOnSerializing(value, Serializer.Context); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int initialDepth = writer.Top; foreach (JsonProperty property in contract.Properties) { try { object memberValue; JsonContract memberContract; if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) continue; writer.WritePropertyName(property.PropertyName); SerializeValue(writer, memberValue, memberContract, property, contract, member); } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, writer.ContainerPath, ex)) HandleError(writer, initialDepth); else throw; } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); contract.InvokeOnSerialized(value, Serializer.Context); }
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id) { ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); Type underlyingType = contract.UnderlyingType; IDictionary <JsonProperty, object> dictionary = ResolvePropertyAndConstructorValues(contract, reader, underlyingType); IDictionary <ParameterInfo, object> dictionary2 = ((IEnumerable <ParameterInfo>)constructorInfo.GetParameters()).ToDictionary((Func <ParameterInfo, ParameterInfo>)((ParameterInfo p) => p), (Func <ParameterInfo, object>)((ParameterInfo p) => null)); IDictionary <JsonProperty, object> dictionary3 = new Dictionary <JsonProperty, object>(); foreach (KeyValuePair <JsonProperty, object> item in dictionary) { ParameterInfo key = dictionary2.ForgivingCaseSensitiveFind((KeyValuePair <ParameterInfo, object> kv) => kv.Key.Name, item.Key.UnderlyingName).Key; if (key != null) { dictionary2[key] = item.Value; } else { dictionary3.Add(item); } } object obj = constructorInfo.Invoke(dictionary2.Values.ToArray()); if (id != null) { base.Serializer.ReferenceResolver.AddReference(this, id, obj); } contract.InvokeOnDeserializing(obj, base.Serializer.Context); foreach (KeyValuePair <JsonProperty, object> item2 in dictionary3) { JsonProperty key2 = item2.Key; object value = item2.Value; if (ShouldSetPropertyValue(item2.Key, item2.Value)) { key2.ValueProvider.SetValue(obj, value); } else { if (key2.Writable || value == null) { continue; } JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(key2.PropertyType); if (jsonContract is JsonArrayContract) { JsonArrayContract jsonArrayContract = jsonContract as JsonArrayContract; object value2 = key2.ValueProvider.GetValue(obj); if (value2 == null) { continue; } IWrappedCollection wrappedCollection = jsonArrayContract.CreateWrapper(value2); IWrappedCollection wrappedCollection2 = jsonArrayContract.CreateWrapper(value); foreach (object item3 in wrappedCollection2) { wrappedCollection.Add(item3); } } else { if (!(jsonContract is JsonDictionaryContract)) { continue; } JsonDictionaryContract jsonDictionaryContract = jsonContract as JsonDictionaryContract; object value3 = key2.ValueProvider.GetValue(obj); if (value3 == null) { continue; } IWrappedDictionary wrappedDictionary = jsonDictionaryContract.CreateWrapper(value3); IWrappedDictionary wrappedDictionary2 = jsonDictionaryContract.CreateWrapper(value); foreach (DictionaryEntry item4 in wrappedDictionary2) { wrappedDictionary.Add(item4.Key, item4.Value); } } } } contract.InvokeOnDeserialized(obj, base.Serializer.Context); return(obj); }
/// <summary> /// Initializes a new instance of the <see cref="JsonPropertyCollection"/> class. /// </summary> /// <param name="contract">The contract.</param> public JsonPropertyCollection(JsonObjectContract contract) { ValidationUtils.ArgumentNotNull(contract, "contract"); _contract = contract; }
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract) { contract.InvokeOnSerializing(value); string s; if (TryConvertToString(value, contract.UnderlyingType, out s)) { writer.WriteValue(s); contract.InvokeOnSerialized(value); return; } SerializeStack.Add(value); writer.WriteStartObject(); bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects); if (isReference) { writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(Serializer.ReferenceResolver.GetReference(value)); } if (HasFlag(Serializer.TypeNameHandling, TypeNameHandling.Objects)) { WriteTypeProperty(writer, contract.UnderlyingType); } int initialDepth = writer.Top; foreach (JsonProperty property in contract.Properties) { try { if (!property.Ignored && property.Readable) { object memberValue = property.ValueProvider.GetValue(value); JsonContract memberContract = GetContractSafe(memberValue); WriteMemberInfoProperty(writer, value, memberValue, property, memberContract); } } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, ex)) { HandleError(writer, initialDepth); } else { throw; } } } writer.WriteEndObject(); SerializeStack.RemoveAt(SerializeStack.Count - 1); contract.InvokeOnSerialized(value); }
private void SerializeObject( JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { this.OnSerializing(writer, (JsonContract)contract, value); this._serializeStack.Add(value); this.WriteObjectStart(writer, value, (JsonContract)contract, member, collectionContract, containerProperty); int top = writer.Top; for (int index = 0; index < contract.Properties.Count; ++index) { JsonProperty property = contract.Properties[index]; try { JsonContract memberContract; object memberValue; if (this.CalculatePropertyValues(writer, value, (JsonContainerContract)contract, member, property, out memberContract, out memberValue)) { property.WritePropertyName(writer); this.SerializeValue(writer, memberValue, memberContract, property, (JsonContainerContract)contract, member); } } catch (Exception ex) { if (this.IsErrorHandled(value, (JsonContract)contract, (object)property.PropertyName, (IJsonLineInfo)null, writer.ContainerPath, ex)) { this.HandleError(writer, top); } else { throw; } } } if (contract.ExtensionDataGetter != null) { IEnumerable <KeyValuePair <object, object> > keyValuePairs = contract.ExtensionDataGetter(value); if (keyValuePairs != null) { foreach (KeyValuePair <object, object> keyValuePair in keyValuePairs) { JsonContract contractSafe1 = this.GetContractSafe(keyValuePair.Key); JsonContract contractSafe2 = this.GetContractSafe(keyValuePair.Value); string propertyName = this.GetPropertyName(writer, keyValuePair.Key, contractSafe1, out bool _); if (this.ShouldWriteReference(keyValuePair.Value, (JsonProperty)null, contractSafe2, (JsonContainerContract)contract, member)) { writer.WritePropertyName(propertyName); this.WriteReference(writer, keyValuePair.Value); } else if (this.CheckForCircularReference(writer, keyValuePair.Value, (JsonProperty)null, contractSafe2, (JsonContainerContract)contract, member)) { writer.WritePropertyName(propertyName); this.SerializeValue(writer, keyValuePair.Value, contractSafe2, (JsonProperty)null, (JsonContainerContract)contract, member); } } } } writer.WriteEndObject(); this._serializeStack.RemoveAt(this._serializeStack.Count - 1); this.OnSerialized(writer, (JsonContract)contract, value); }
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ConstructorInfo constructorInfo, string id) { ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); // only need to keep a track of properies presence if they are required or a value should be defaulted if missing Dictionary<JsonProperty, PropertyPresence> propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None) : null; Type objectType = contract.UnderlyingType; if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using a non-default constructor '{1}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, constructorInfo)), null); IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, containerProperty, reader, objectType); IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object) null); IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>(); foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues) { ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key; if (matchingConstructorParameter != null) constructorParameters[matchingConstructorParameter] = propertyValue.Value; else remainingPropertyValues.Add(propertyValue); if (propertiesPresence != null) { // map from constructor property to normal property var property = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == propertyValue.Key.PropertyName); if (property != null) propertiesPresence[property] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value; } } object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray()); if (id != null) AddReference(reader, id, createdObject); OnDeserializing(reader, contract, createdObject); // go through unused values and set the newly created object's properties foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues) { JsonProperty property = remainingPropertyValue.Key; object value = remainingPropertyValue.Value; if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) { property.ValueProvider.SetValue(createdObject, value); } else if (!property.Writable && value != null) { // handle readonly collection/dictionary properties JsonContract propertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); if (propertyContract.ContractType == JsonContractType.Array) { JsonArrayContract propertyArrayContract = (JsonArrayContract)propertyContract; object createdObjectCollection = property.ValueProvider.GetValue(createdObject); if (createdObjectCollection != null) { IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection); IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value); foreach (object newValue in newValues) { createdObjectCollectionWrapper.Add(newValue); } } } else if (propertyContract.ContractType == JsonContractType.Dictionary) { JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)propertyContract; object createdObjectDictionary = property.ValueProvider.GetValue(createdObject); if (createdObjectDictionary != null) { IDictionary targetDictionary = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(createdObjectDictionary) : (IDictionary) createdObjectDictionary; IDictionary newValues = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(value) : (IDictionary) value; foreach (DictionaryEntry newValue in newValues) { targetDictionary.Add(newValue.Key, newValue.Value); } } } } } EndObject(createdObject, reader, contract, reader.Depth, propertiesPresence); OnDeserialized(reader, contract, createdObject); return createdObject; }
private static void SetExtensionDataDelegates(JsonObjectContract contract, MemberInfo member) { JsonExtensionDataAttribute attribute = ReflectionUtils.GetAttribute <JsonExtensionDataAttribute>(member); if (attribute == null) { return; } Type type = ReflectionUtils.GetMemberUnderlyingType(member); Type type2; ReflectionUtils.ImplementsGenericDefinition(type, typeof(IDictionary <, >), out type2); Type type3 = type2.GetGenericArguments()[0]; Type type4 = type2.GetGenericArguments()[1]; bool isJTokenValueType = typeof(JToken).IsAssignableFrom(type4); if (ReflectionUtils.IsGenericDefinition(type, typeof(IDictionary <, >))) { type = typeof(Dictionary <, >).MakeGenericType(new Type[] { type3, type4 }); } MethodInfo method = type.GetMethod("Add", new Type[] { type3, type4 }); Func <object, object> getExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateGet <object>(member); Action <object, object> setExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateSet <object>(member); Func <object> createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor <object>(type); MethodCall <object, object> setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall <object>(method); ExtensionDataSetter extensionDataSetter = delegate(object o, string key, object value) { object obj = getExtensionDataDictionary(o); if (obj == null) { obj = createExtensionDataDictionary(); setExtensionDataDictionary(o, obj); } if (isJTokenValueType && !(value is JToken)) { value = JToken.FromObject(value); } setExtensionDataDictionaryValue(obj, new object[] { key, value }); }; Type type5 = typeof(DefaultContractResolver.DictionaryEnumerator <, >).MakeGenericType(new Type[] { type3, type4 }); ConstructorInfo method2 = type5.GetConstructors().First <ConstructorInfo>(); MethodCall <object, object> createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall <object>(method2); ExtensionDataGetter extensionDataGetter = delegate(object o) { object obj = getExtensionDataDictionary(o); if (obj == null) { return(null); } return((IEnumerable <KeyValuePair <object, object> >)createEnumerableWrapper(null, new object[] { obj })); }; if (attribute.ReadData) { contract.ExtensionDataSetter = extensionDataSetter; } if (attribute.WriteData) { contract.ExtensionDataGetter = extensionDataGetter; } }
private void GenerateObjectSchema(JSchema schema, Type type, JsonObjectContract contract) { foreach (JsonProperty property in contract.Properties) { if (!property.Ignored) { bool optional = property.NullValueHandling == NullValueHandling.Ignore || HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) || property.ShouldSerialize != null || property.GetIsSpecified != null; Required required = property.Required; if (DataAnnotationHelpers.GetRequired(property)) required = Required.Always; JSchema propertySchema = GenerateInternal(property.PropertyType, required, property, contract); if (property.DefaultValue != null) propertySchema.Default = JToken.FromObject(property.DefaultValue); schema.Properties.Add(property.PropertyName, propertySchema); if (!optional) schema.Required.Add(property.PropertyName); } } if (type.IsSealed()) schema.AllowAdditionalProperties = false; }
/// <summary> /// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>. /// </summary> /// <param name="contract">The member's declaring types <see cref="JsonObjectContract"/>.</param> /// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param> /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns> protected virtual JsonProperty CreateProperty(JsonObjectContract contract, MemberInfo member) { JsonProperty property = new JsonProperty(); property.Member = member; #if !PocketPC && !SILVERLIGHT && !MONO DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType); DataMemberAttribute dataMemberAttribute; if (dataContractAttribute != null) { dataMemberAttribute = JsonTypeReflector.GetAttribute <DataMemberAttribute>(member); } else { dataMemberAttribute = null; } #endif JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute <JsonPropertyAttribute>(member); bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute <JsonIgnoreAttribute>(member) != null); string mappedName; if (propertyAttribute != null && propertyAttribute.PropertyName != null) { mappedName = propertyAttribute.PropertyName; } #if !PocketPC && !SILVERLIGHT && !MONO else if (dataMemberAttribute != null && dataMemberAttribute.Name != null) { mappedName = dataMemberAttribute.Name; } #endif else { mappedName = member.Name; } property.PropertyName = ResolvePropertyName(mappedName); if (propertyAttribute != null) { property.Required = propertyAttribute.IsRequired; } #if !PocketPC && !SILVERLIGHT && !MONO else if (dataMemberAttribute != null) { property.Required = dataMemberAttribute.IsRequired; } #endif else { property.Required = false; } property.Ignored = (hasIgnoreAttribute || (contract.MemberSerialization == MemberSerialization.OptIn && propertyAttribute == null #if !PocketPC && !SILVERLIGHT && !MONO && dataMemberAttribute == null #endif )); property.Readable = ReflectionUtils.CanReadMemberValue(member); property.Writable = ReflectionUtils.CanSetMemberValue(member); property.MemberConverter = JsonTypeReflector.GetConverter(member, ReflectionUtils.GetMemberUnderlyingType(member)); DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute <DefaultValueAttribute>(member); property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null; property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null; property.DefaultValueHandling = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null; property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null; property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null; return(property); }
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id) { contract.InvokeOnDeserializing(newObject, Serializer.Context); Dictionary<JsonProperty, PropertyPresence> propertiesPresence = contract.Properties.ToDictionary(m => m, m => PropertyPresence.None); if (id != null) Serializer.ReferenceResolver.AddReference(this, id, newObject); int initialDepth = reader.Depth; do { switch (reader.TokenType) { case JsonToken.PropertyName: { string memberName = reader.Value.ToString(); try { // attempt exact case match first // then try match ignoring case JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); if (property == null) { if (Serializer.MissingMemberHandling == MissingMemberHandling.Error) throw CreateSerializationException(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name)); reader.Skip(); continue; } if (property.PropertyContract == null) property.PropertyContract = GetContractSafe(property.PropertyType); JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter); if (!ReadForType(reader, property.PropertyContract, propertyConverter != null, false)) throw CreateSerializationException(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); SetPropertyPresence(reader, property, propertiesPresence); SetPropertyValue(property, propertyConverter, reader, newObject); } catch (Exception ex) { if (IsErrorHandled(newObject, contract, memberName, reader.Path, ex)) HandleError(reader, initialDepth); else throw; } } break; case JsonToken.EndObject: { foreach (KeyValuePair<JsonProperty, PropertyPresence> propertyPresence in propertiesPresence) { JsonProperty property = propertyPresence.Key; PropertyPresence presence = propertyPresence.Value; if (presence == PropertyPresence.None || presence == PropertyPresence.Null) { try { switch (presence) { case PropertyPresence.None: if (property.Required == Required.AllowNull || property.Required == Required.Always) throw CreateSerializationException(reader, "Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); if (property.PropertyContract == null) property.PropertyContract = GetContractSafe(property.PropertyType); if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Populate) && property.Writable) property.ValueProvider.SetValue(newObject, EnsureType(reader, property.DefaultValue, CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType)); break; case PropertyPresence.Null: if (property.Required == Required.Always) throw CreateSerializationException(reader, "Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); break; } } catch (Exception ex) { if (IsErrorHandled(newObject, contract, property.PropertyName, reader.Path, ex)) HandleError(reader, initialDepth); else throw; } } } contract.InvokeOnDeserialized(newObject, Serializer.Context); return newObject; } case JsonToken.Comment: // ignore break; default: throw CreateSerializationException(reader, "Unexpected token when deserializing object: " + reader.TokenType); } } while (reader.Read()); throw CreateSerializationException(reader, "Unexpected end when deserializing object."); }
private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { CheckedRead(reader); string text = null; if (reader.TokenType == JsonToken.PropertyName) { bool flag; do { string a = reader.Value.ToString(); if (string.Equals(a, "$ref", StringComparison.Ordinal)) { CheckedRead(reader); if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null) { throw new JsonSerializationException("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 new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, "$ref")); } return(base.Serializer.ReferenceResolver.ResolveReference(this, text2)); } flag = true; } else if (string.Equals(a, "$type", StringComparison.Ordinal)) { CheckedRead(reader); string text3 = reader.Value.ToString(); CheckedRead(reader); if ((member?.TypeNameHandling ?? base.Serializer.TypeNameHandling) != 0) { ReflectionUtils.SplitFullyQualifiedTypeName(text3, out var typeName, out var assemblyName); Type type; try { type = base.Serializer.Binder.BindToType(assemblyName, typeName); } catch (Exception innerException) { throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, text3), innerException); } if (type == null) { throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, text3)); } if (!(objectType?.IsAssignableFrom(type) ?? true)) { throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, type.AssemblyQualifiedName, objectType.AssemblyQualifiedName)); } objectType = type; contract = GetContractSafe(type); } flag = true; } else if (string.Equals(a, "$id", StringComparison.Ordinal)) { CheckedRead(reader); text = ((reader.Value != null) ? reader.Value.ToString() : null); CheckedRead(reader); flag = true; } else { if (string.Equals(a, "$values", StringComparison.Ordinal)) { CheckedRead(reader); object result = CreateList(reader, objectType, contract, member, existingValue, text); CheckedRead(reader); return(result); } flag = false; } }while (flag && reader.TokenType == JsonToken.PropertyName); } if (!HasDefinedType(objectType)) { return(CreateJObject(reader)); } if (contract == null) { throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); } JsonDictionaryContract jsonDictionaryContract = contract as JsonDictionaryContract; if (jsonDictionaryContract != null) { if (existingValue == null) { return(CreateAndPopulateDictionary(reader, jsonDictionaryContract, text)); } return(PopulateDictionary(jsonDictionaryContract.CreateWrapper(existingValue), reader, jsonDictionaryContract, text)); } JsonObjectContract jsonObjectContract = contract as JsonObjectContract; if (jsonObjectContract != null) { if (existingValue == null) { return(CreateAndPopulateObject(reader, jsonObjectContract, text)); } return(PopulateObject(existingValue, reader, jsonObjectContract, text)); } JsonPrimitiveContract jsonPrimitiveContract = contract as JsonPrimitiveContract; if (jsonPrimitiveContract != null && reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), "$value", StringComparison.Ordinal)) { CheckedRead(reader); object result2 = CreateValueInternal(reader, objectType, jsonPrimitiveContract, member, existingValue); CheckedRead(reader); return(result2); } JsonISerializableContract jsonISerializableContract = contract as JsonISerializableContract; if (jsonISerializableContract != null) { return(CreateISerializable(reader, jsonISerializableContract, text)); } throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); }
private IDictionary <JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonReader reader, Type objectType) { 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.ConstructorParameters.GetClosestMatchProperty(text) ?? contract.Properties.GetClosestMatchProperty(text); if (jsonProperty != null) { if (!ReadForType(reader, jsonProperty.PropertyType, jsonProperty.Converter)) { throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text)); } if (!jsonProperty.Ignored) { dictionary[jsonProperty] = CreateValueProperty(reader, jsonProperty, null, gottenCurrentValue: true, null); } else { reader.Skip(); } break; } if (!reader.Read()) { throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, text)); } if (base.Serializer.MissingMemberHandling == MissingMemberHandling.Error) { throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, text, objectType.Name)); } reader.Skip(); break; } case JsonToken.EndObject: flag = true; break; default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); case JsonToken.Comment: break; } }while (!flag && reader.Read()); return(dictionary); }
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { contract.InvokeOnSerializing(value, Serializer.Context); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int initialDepth = writer.Top; foreach (JsonProperty property in contract.Properties) { try { if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value)) { if (property.PropertyContract == null) { property.PropertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType); } object memberValue = property.ValueProvider.GetValue(value); JsonContract memberContract = (property.PropertyContract.UnderlyingType.IsSealed()) ? property.PropertyContract : GetContractSafe(memberValue); if (ShouldWriteProperty(memberValue, property)) { string propertyName = property.PropertyName; if (ShouldWriteReference(memberValue, property, memberContract, contract, member)) { writer.WritePropertyName(propertyName); WriteReference(writer, memberValue); continue; } if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member)) { continue; } if (memberValue == null) { Required resolvedRequired = property._required ?? contract.ItemRequired ?? Required.Default; if (resolvedRequired == Required.Always) { throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null); } } writer.WritePropertyName(propertyName); SerializeValue(writer, memberValue, memberContract, property, contract, member); } } } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); contract.InvokeOnSerialized(value, Serializer.Context); }
private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id) { object newObject = null; if (contract.UnderlyingType.IsInterface || contract.UnderlyingType.IsAbstract) throw new JsonSerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) { newObject = contract.DefaultCreator(); } if (newObject != null) { PopulateObject(newObject, reader, contract, id); return newObject; } return CreateObjectFromNonDefaultConstructor(reader, contract, id); }
/// <summary> /// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>. /// </summary> /// <param name="contract">The member's declaring types <see cref="JsonObjectContract"/>.</param> /// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param> /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns> protected virtual JsonProperty CreateProperty(JsonObjectContract contract, MemberInfo member) { JsonProperty property = new JsonProperty(); property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member); property.ValueProvider = CreateMemberValueProvider(member); // resolve converter for property // the class type might have a converter but the property converter takes presidence property.Converter = JsonTypeReflector.GetJsonConverter(member, property.PropertyType); #if !PocketPC && !NET20 DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType); DataMemberAttribute dataMemberAttribute; if (dataContractAttribute != null) { dataMemberAttribute = JsonTypeReflector.GetAttribute <DataMemberAttribute>(member); } else { dataMemberAttribute = null; } #endif JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute <JsonPropertyAttribute>(member); bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute <JsonIgnoreAttribute>(member) != null); string mappedName; if (propertyAttribute != null && propertyAttribute.PropertyName != null) { mappedName = propertyAttribute.PropertyName; } #if !PocketPC && !NET20 else if (dataMemberAttribute != null && dataMemberAttribute.Name != null) { mappedName = dataMemberAttribute.Name; } #endif else { mappedName = member.Name; } property.PropertyName = ResolvePropertyName(mappedName); if (propertyAttribute != null) { property.Required = propertyAttribute.Required; } #if !PocketPC && !NET20 else if (dataMemberAttribute != null) { property.Required = (dataMemberAttribute.IsRequired) ? Required.AllowNull : Required.Default; } #endif else { property.Required = Required.Default; } property.Ignored = (hasIgnoreAttribute || (contract.MemberSerialization == MemberSerialization.OptIn && propertyAttribute == null #if !PocketPC && !NET20 && dataMemberAttribute == null #endif )); bool allowNonPublicAccess = false; if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic) { allowNonPublicAccess = true; } if (propertyAttribute != null) { allowNonPublicAccess = true; } #if !PocketPC && !NET20 if (dataMemberAttribute != null) { allowNonPublicAccess = true; } #endif property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess); property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess); property.MemberConverter = JsonTypeReflector.GetJsonConverter(member, ReflectionUtils.GetMemberUnderlyingType(member)); DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute <DefaultValueAttribute>(member); property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null; property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null; property.DefaultValueHandling = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null; property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null; property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null; property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null; property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null; property.ShouldSerialize = CreateShouldSerializeTest(member); return(property); }
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id) { contract.InvokeOnDeserializing(newObject, Serializer.Context); Dictionary<JsonProperty, RequiredValue> requiredProperties = contract.Properties.Where(m => m.Required != Required.Default).ToDictionary(m => m, m => RequiredValue.None); if (id != null) Serializer.ReferenceResolver.AddReference(id, newObject); int initialDepth = reader.Depth; do { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); // attempt exact case match first // then try match ignoring case JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); if (property == null) { if (Serializer.MissingMemberHandling == MissingMemberHandling.Error) throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name)); reader.Skip(); continue; } if (property.PropertyType == typeof(byte[])) { reader.ReadAsBytes(); } else { if (!reader.Read()) throw new JsonSerializationException( "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); } SetRequiredProperty(reader, property, requiredProperties); try { SetPropertyValue(property, reader, newObject); } catch (Exception ex) { if (IsErrorHandled(newObject, contract, memberName, ex)) HandleError(reader, initialDepth); else throw; } break; case JsonToken.EndObject: foreach (KeyValuePair<JsonProperty, RequiredValue> requiredProperty in requiredProperties) { if (requiredProperty.Value == RequiredValue.None) throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName)); if (requiredProperty.Key.Required == Required.Always && requiredProperty.Value == RequiredValue.Null) throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName)); } contract.InvokeOnDeserialized(newObject, Serializer.Context); return newObject; case JsonToken.Comment: // ignore break; default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); } } while (reader.Read()); throw new JsonSerializationException("Unexpected end when deserializing object."); }
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id) { contract.InvokeOnDeserializing(newObject, Serializer.Context); Dictionary <JsonProperty, RequiredValue> requiredProperties = contract.Properties.Where(m => m.Required != Required.Default).ToDictionary(m => m, m => RequiredValue.None); if (id != null) { Serializer.ReferenceResolver.AddReference(id, newObject); } int initialDepth = reader.Depth; do { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); // attempt exact case match first // then try match ignoring case JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); if (property == null) { if (Serializer.MissingMemberHandling == MissingMemberHandling.Error) { throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name)); } reader.Skip(); continue; } if (!ReadForType(reader, property.PropertyType, property.Converter)) { throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); } SetRequiredProperty(reader, property, requiredProperties); try { SetPropertyValue(property, reader, newObject); } catch (Exception ex) { if (IsErrorHandled(newObject, contract, memberName, ex)) { HandleError(reader, initialDepth); } else { throw; } } break; case JsonToken.EndObject: foreach (KeyValuePair <JsonProperty, RequiredValue> requiredProperty in requiredProperties) { if (requiredProperty.Value == RequiredValue.None) { throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName)); } if (requiredProperty.Key.Required == Required.Always && requiredProperty.Value == RequiredValue.Null) { throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName)); } } contract.InvokeOnDeserialized(newObject, Serializer.Context); return(newObject); case JsonToken.Comment: // ignore break; default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); } } while (reader.Read()); throw new JsonSerializationException("Unexpected end when deserializing object."); }
private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor<object> creator, string id) { ValidationUtils.ArgumentNotNull(creator, "creator"); // only need to keep a track of properies presence if they are required or a value should be defaulted if missing Dictionary<JsonProperty, PropertyPresence> propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None) : null; Type objectType = contract.UnderlyingType; if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) { string parameters = string.Join(", ", contract.CreatorParameters.Select(p => 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, parameters)), null); } IDictionary<string, object> extensionData; IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndCreatorValues(contract, containerProperty, reader, objectType, out extensionData); object[] creatorParameterValues = new object[contract.CreatorParameters.Count]; IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>(); foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues) { JsonProperty property = propertyValue.Key; JsonProperty matchingCreatorParameter; if (contract.CreatorParameters.Contains(property)) { matchingCreatorParameter = property; } else { // check to see if a parameter with the same name as the underlying property name exists and match to that matchingCreatorParameter = contract.CreatorParameters.ForgivingCaseSensitiveFind(p => p.PropertyName, property.UnderlyingName); } if (matchingCreatorParameter != null) { int i = contract.CreatorParameters.IndexOf(matchingCreatorParameter); creatorParameterValues[i] = propertyValue.Value; } else { remainingPropertyValues.Add(propertyValue); } if (propertiesPresence != null) { // map from creator property to normal property JsonProperty presenceProperty = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == property.PropertyName); if (presenceProperty != null) propertiesPresence[presenceProperty] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value; } } object createdObject = creator(creatorParameterValues); if (id != null) AddReference(reader, id, createdObject); OnDeserializing(reader, contract, createdObject); // go through unused values and set the newly created object's properties foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues) { JsonProperty property = remainingPropertyValue.Key; object value = remainingPropertyValue.Value; if (ShouldSetPropertyValue(property, value)) { property.ValueProvider.SetValue(createdObject, value); } else if (!property.Writable && value != null) { // handle readonly collection/dictionary properties JsonContract propertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); if (propertyContract.ContractType == JsonContractType.Array) { JsonArrayContract propertyArrayContract = (JsonArrayContract)propertyContract; object createdObjectCollection = property.ValueProvider.GetValue(createdObject); if (createdObjectCollection != null) { IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection); IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value); foreach (object newValue in newValues) { createdObjectCollectionWrapper.Add(newValue); } } } else if (propertyContract.ContractType == JsonContractType.Dictionary) { JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)propertyContract; object createdObjectDictionary = property.ValueProvider.GetValue(createdObject); if (createdObjectDictionary != null) { IDictionary targetDictionary = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(createdObjectDictionary) : (IDictionary)createdObjectDictionary; IDictionary newValues = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(value) : (IDictionary)value; foreach (DictionaryEntry newValue in newValues) { targetDictionary.Add(newValue.Key, newValue.Value); } } } } } if (extensionData != null) { foreach (KeyValuePair<string, object> e in extensionData) { contract.ExtensionDataSetter(createdObject, e.Key, e.Value); } } EndObject(createdObject, reader, contract, reader.Depth, propertiesPresence); OnDeserialized(reader, contract, createdObject); return createdObject; }
private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { OnSerializing(writer, contract, value); _serializeStack.Add(value); WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); int initialDepth = writer.Top; for (int index = 0; index < contract.Properties.Count; index++) { JsonProperty property = contract.Properties[index]; try { object memberValue; JsonContract memberContract; if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) { continue; } property.WritePropertyName(writer); SerializeValue(writer, memberValue, memberContract, property, contract, member); } catch (Exception ex) { if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) { HandleError(writer, initialDepth); } else { throw; } } } if (contract.ExtensionDataGetter != null) { IEnumerable <KeyValuePair <object, object> > extensionData = contract.ExtensionDataGetter(value); if (extensionData != null) { foreach (KeyValuePair <object, object> e in extensionData) { JsonContract keyContract = GetContractSafe(e.Key); JsonContract valueContract = GetContractSafe(e.Value); bool escape; string propertyName = GetPropertyName(writer, e.Key, keyContract, out escape); if (ShouldWriteReference(e.Value, null, valueContract, contract, member)) { writer.WritePropertyName(propertyName); WriteReference(writer, e.Value); } else { if (!CheckForCircularReference(writer, e.Value, null, valueContract, contract, member)) { continue; } writer.WritePropertyName(propertyName); SerializeValue(writer, e.Value, valueContract, null, contract, member); } } } } writer.WriteEndObject(); _serializeStack.RemoveAt(_serializeStack.Count - 1); OnSerialized(writer, contract, value); }
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id) { OnDeserializing(reader, contract, newObject); // only need to keep a track of properies presence if they are required or a value should be defaulted if missing Dictionary<JsonProperty, PropertyPresence> propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None) : null; if (id != null) AddReference(reader, id, newObject); int initialDepth = reader.Depth; bool finished = false; do { switch (reader.TokenType) { case JsonToken.PropertyName: { string memberName = reader.Value.ToString(); try { // attempt exact case match first // then try match ignoring case JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); if (property == 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, memberName, 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, memberName, contract.UnderlyingType.Name)); if (!reader.Read()) break; SetExtensionData(contract, member, reader, memberName, newObject); continue; } if (property.PropertyContract == null) property.PropertyContract = GetContractSafe(property.PropertyType); JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, member); if (!ReadForType(reader, property.PropertyContract, propertyConverter != null)) throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); SetPropertyPresence(reader, property, propertiesPresence); // set extension data if property is ignored or readonly if (!SetPropertyValue(property, propertyConverter, contract, member, reader, newObject)) SetExtensionData(contract, member, reader, memberName, newObject); } catch (Exception ex) { if (IsErrorHandled(newObject, contract, memberName, reader as IJsonLineInfo, reader.Path, ex)) HandleError(reader, true, initialDepth); else throw; } } break; case JsonToken.EndObject: finished = true; break; case JsonToken.Comment: // ignore break; default: throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); } } while (!finished && reader.Read()); if (!finished) ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object."); EndObject(newObject, reader, contract, initialDepth, propertiesPresence); OnDeserialized(reader, contract, newObject); return newObject; }
private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { CheckedRead(reader); string id = null; if (reader.TokenType == JsonToken.PropertyName) { bool specialProperty; do { string propertyName = reader.Value.ToString(); if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal)) { CheckedRead(reader); if (reader.TokenType != JsonToken.String) { throw new JsonSerializationException("JSON reference {0} property must have a string value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); } string reference = reader.Value.ToString(); CheckedRead(reader); if (reader.TokenType == JsonToken.PropertyName) { throw new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); } return(Serializer.ReferenceResolver.ResolveReference(reference)); } else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal)) { CheckedRead(reader); string qualifiedTypeName = reader.Value.ToString(); CheckedRead(reader); if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) != TypeNameHandling.None) { string typeName; string assemblyName; ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName); Type specifiedType; try { specifiedType = Serializer.Binder.BindToType(assemblyName, typeName); } catch (Exception ex) { throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex); } if (specifiedType == null) { throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName)); } if (objectType != null && !objectType.IsAssignableFrom(specifiedType)) { throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName)); } objectType = specifiedType; contract = GetContractSafe(specifiedType); } specialProperty = true; } else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal)) { CheckedRead(reader); id = reader.Value.ToString(); CheckedRead(reader); specialProperty = true; } else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal)) { CheckedRead(reader); object list = CreateList(reader, objectType, contract, member, existingValue, id); CheckedRead(reader); return(list); } else { specialProperty = false; } } while (specialProperty && reader.TokenType == JsonToken.PropertyName); } if (!HasDefinedType(objectType)) { return(CreateJObject(reader)); } if (contract == null) { throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); } JsonDictionaryContract dictionaryContract = contract as JsonDictionaryContract; if (dictionaryContract != null) { if (existingValue == null) { return(CreateAndPopulateDictionary(reader, dictionaryContract, id)); } return(PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id)); } JsonObjectContract objectContract = contract as JsonObjectContract; if (objectContract != null) { if (existingValue == null) { return(CreateAndPopulateObject(reader, objectContract, id)); } return(PopulateObject(existingValue, reader, objectContract, id)); } #if !SILVERLIGHT && !PocketPC JsonISerializableContract serializableContract = contract as JsonISerializableContract; if (serializableContract != null) { return(CreateISerializable(reader, serializableContract, id)); } #endif throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); }
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 object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, string id) { Type objectType = contract.UnderlyingType; if (contract.ParametrizedConstructor == null) { throw new JsonSerializationException("Unable to find a constructor to use for type {0}. A class should either have a default constructor or only one constructor with arguments.".FormatWith(CultureInfo.InvariantCulture, objectType)); } // create a dictionary to put retrieved values into IDictionary <JsonProperty, object> propertyValues = contract.Properties.Where(p => !p.Ignored).ToDictionary(kv => kv, kv => (object)null); bool exit = false; do { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); if (!reader.Read()) { throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); } // attempt exact case match first // then try match ignoring case JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); if (property != null) { if (!property.Ignored) { propertyValues[property] = CreateValueProperty(reader, property, null, true, null); } else { reader.Skip(); } } else { if (Serializer.MissingMemberHandling == MissingMemberHandling.Error) { throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name)); } reader.Skip(); } break; case JsonToken.EndObject: exit = true; break; default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); } } while (!exit && reader.Read()); IDictionary <ParameterInfo, object> constructorParameters = contract.ParametrizedConstructor.GetParameters().ToDictionary(p => p, p => (object)null); IDictionary <JsonProperty, object> remainingPropertyValues = new Dictionary <JsonProperty, object>(); foreach (KeyValuePair <JsonProperty, object> propertyValue in propertyValues) { ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key; if (matchingConstructorParameter != null) { constructorParameters[matchingConstructorParameter] = propertyValue.Value; } else { remainingPropertyValues.Add(propertyValue); } } object createdObject = contract.ParametrizedConstructor.Invoke(constructorParameters.Values.ToArray()); if (id != null) { Serializer.ReferenceResolver.AddReference(id, createdObject); } contract.InvokeOnDeserializing(createdObject, Serializer.Context); // go through unused values and set the newly created object's properties foreach (KeyValuePair <JsonProperty, object> remainingPropertyValue in remainingPropertyValues) { JsonProperty property = remainingPropertyValue.Key; object value = remainingPropertyValue.Value; if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) { property.ValueProvider.SetValue(createdObject, value); } } contract.InvokeOnDeserialized(createdObject, Serializer.Context); return(createdObject); }
private void EndObject(object newObject, JsonReader reader, JsonObjectContract contract, int initialDepth, Dictionary<JsonProperty, PropertyPresence> propertiesPresence) { if (propertiesPresence != null) { foreach (KeyValuePair<JsonProperty, PropertyPresence> propertyPresence in propertiesPresence) { JsonProperty property = propertyPresence.Key; PropertyPresence presence = propertyPresence.Value; if (presence == PropertyPresence.None || presence == PropertyPresence.Null) { try { Required resolvedRequired = property._required ?? contract.ItemRequired ?? Required.Default; switch (presence) { case PropertyPresence.None: if (resolvedRequired == Required.AllowNull || resolvedRequired == Required.Always) throw JsonSerializationException.Create(reader, "Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); if (property.PropertyContract == null) property.PropertyContract = GetContractSafe(property.PropertyType); if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) && property.Writable) property.ValueProvider.SetValue(newObject, EnsureType(reader, property.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType)); break; case PropertyPresence.Null: if (resolvedRequired == Required.Always) throw JsonSerializationException.Create(reader, "Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); break; } } catch (Exception ex) { if (IsErrorHandled(newObject, contract, property.PropertyName, reader as IJsonLineInfo, reader.Path, ex)) HandleError(reader, true, initialDepth); else throw; } } } } }
private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id) { ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); Type underlyingType = contract.UnderlyingType; IDictionary <JsonProperty, object> dictionary = ResolvePropertyAndConstructorValues(contract, reader, underlyingType); IDictionary <ParameterInfo, object> dictionary2 = ((IEnumerable <ParameterInfo>)constructorInfo.GetParameters()).ToDictionary((Func <ParameterInfo, ParameterInfo>)((ParameterInfo p) => p), (Func <ParameterInfo, object>)((ParameterInfo p) => null)); IDictionary <JsonProperty, object> dictionary3 = new Dictionary <JsonProperty, object>(); foreach (KeyValuePair <JsonProperty, object> item in dictionary) { ParameterInfo key = dictionary2.ForgivingCaseSensitiveFind((KeyValuePair <ParameterInfo, object> kv) => kv.Key.Name, item.Key.UnderlyingName).Key; if (key != null) { dictionary2[key] = item.Value; } else { dictionary3.Add(item); } } object obj = constructorInfo.Invoke(dictionary2.Values.ToArray()); if (id != null) { base.Serializer.ReferenceResolver.AddReference(this, id, obj); } contract.InvokeOnDeserializing(obj, base.Serializer.Context); foreach (KeyValuePair <JsonProperty, object> item2 in dictionary3) { JsonProperty key2 = item2.Key; object value = item2.Value; if (ShouldSetPropertyValue(item2.Key, item2.Value)) { key2.ValueProvider.SetValue(obj, value); } else if (!key2.Writable && value != null) { JsonContract jsonContract = base.Serializer.ContractResolver.ResolveContract(key2.PropertyType); if (jsonContract is JsonArrayContract) { JsonArrayContract jsonArrayContract = jsonContract as JsonArrayContract; object value2 = key2.ValueProvider.GetValue(obj); if (value2 != null) { IWrappedCollection wrappedCollection = jsonArrayContract.CreateWrapper(value2); IWrappedCollection wrappedCollection2 = jsonArrayContract.CreateWrapper(value); IEnumerator enumerator3 = wrappedCollection2.GetEnumerator(); try { while (enumerator3.MoveNext()) { object current3 = enumerator3.Current; wrappedCollection.Add(current3); } } finally { IDisposable disposable; if ((disposable = (enumerator3 as IDisposable)) != null) { disposable.Dispose(); } } } } else if (jsonContract is JsonDictionaryContract) { JsonDictionaryContract jsonDictionaryContract = jsonContract as JsonDictionaryContract; object value3 = key2.ValueProvider.GetValue(obj); if (value3 != null) { IWrappedDictionary wrappedDictionary = jsonDictionaryContract.CreateWrapper(value3); IWrappedDictionary wrappedDictionary2 = jsonDictionaryContract.CreateWrapper(value); IDictionaryEnumerator enumerator4 = wrappedDictionary2.GetEnumerator(); try { while (enumerator4.MoveNext()) { DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator4.Current; wrappedDictionary.Add(dictionaryEntry.Key, dictionaryEntry.Value); } } finally { IDisposable disposable2; if ((disposable2 = (enumerator4 as IDisposable)) != null) { disposable2.Dispose(); } } } } } } contract.InvokeOnDeserialized(obj, base.Serializer.Context); return(obj); }
private Schema CreateObjectSchema(JsonObjectContract jsonContract) { var properties = jsonContract.Properties .Where(p => !p.Ignored) .Where(p => !(_ignoreObsoleteProperties && p.IsObsolete())) .ToDictionary( prop => prop.PropertyName, prop => CreateInlineSchema(prop.PropertyType).WithValidationProperties(prop) ); var required = jsonContract.Properties.Where(prop => prop.IsRequired()) .Select(propInfo => propInfo.PropertyName) .ToList(); var schema = new Schema { required = required.Any() ? required : null, // required can be null but not empty properties = properties, type = "object" }; foreach (var filter in _schemaFilters) { filter.Apply(schema, this, jsonContract.UnderlyingType); } // NOTE: In next major version, _modelFilters will completely replace _schemaFilters var modelFilterContext = new ModelFilterContext(jsonContract.UnderlyingType, jsonContract, this); foreach (var filter in _modelFilters) { filter.Apply(schema, modelFilterContext); } return schema; }
/// <summary> /// Make sure that JsonExtensionData doesn't serialize /// $metadata fields or properties that are in the actual object. /// </summary> /// <param name="objContract">the Json object contract to tweak.</param> private static void FilterJsonExtensionData(JsonObjectContract objContract) { var orig = objContract?.ExtensionDataGetter; if (orig != null) { objContract.ExtensionDataGetter = o => { return orig(o)?.Where(each => { var key = each.Key.ToString(); return !key.StartsWith("$") && objContract.Properties.All(p => p.PropertyName != key); }); }; } }
private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonReader reader, Type objectType) { IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>(); bool exit = false; do { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); // attempt exact case match first // then try match ignoring case JsonProperty property = contract.ConstructorParameters.GetClosestMatchProperty(memberName) ?? contract.Properties.GetClosestMatchProperty(memberName); if (property != null) { if (property.PropertyContract == null) property.PropertyContract = GetContractSafe(property.PropertyType); JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter); if (!ReadForType(reader, property.PropertyContract, propertyConverter != null, false)) throw CreateSerializationException(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); if (!property.Ignored) propertyValues[property] = CreateValueProperty(reader, property, propertyConverter, null, true, null); else reader.Skip(); } else { if (!reader.Read()) throw CreateSerializationException(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); if (Serializer.MissingMemberHandling == MissingMemberHandling.Error) throw CreateSerializationException(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name)); reader.Skip(); } break; case JsonToken.Comment: break; case JsonToken.EndObject: exit = true; break; default: throw CreateSerializationException(reader, "Unexpected token when deserializing object: " + reader.TokenType); } } while (!exit && reader.Read()); return propertyValues; }
static void EnableInvisibleMetadata(JsonObjectContract contract) { if (!typeof(DomainEvent).IsAssignableFrom(contract.UnderlyingType)) return; var property = contract.Properties["Meta"]; property.Ignored = true; contract.OnDeserializedCallbacks.Add((target, context) => property.ValueProvider.SetValue(target, new Metadata())); }
private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id) { object newObject = null; if (contract.UnderlyingType.IsInterface() || contract.UnderlyingType.IsAbstract()) throw CreateSerializationException(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); if (contract.OverrideConstructor != null) { if (contract.OverrideConstructor.GetParameters().Length > 0) return CreateObjectFromNonDefaultConstructor(reader, contract, contract.OverrideConstructor, id); newObject = contract.OverrideConstructor.Invoke(null); } else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || contract.ParametrizedConstructor == null)) { // use the default constructor if it is... // public // non-public and the user has change constructor handling settings // non-public and there is no other constructor newObject = contract.DefaultCreator(); } else if (contract.ParametrizedConstructor != null) { return CreateObjectFromNonDefaultConstructor(reader, contract, contract.ParametrizedConstructor, id); } if (newObject == null) throw CreateSerializationException(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, contract.UnderlyingType)); PopulateObject(newObject, reader, contract, id); return newObject; }
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var contract = new JsonObjectContract(type); return base.CreateProperties(contract.CreatedType, contract.MemberSerialization); }
private object CreateObjectFromNonDefaultConstructor(JsonObjectContract contract, JsonReader reader) { Type objectType = contract.UnderlyingType; // object should have a single constructor ConstructorInfo c = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).SingleOrDefault(); if (c == null) { throw new JsonSerializationException("Could not find a public constructor for type {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); } // create a dictionary to put retrieved values into IDictionary <JsonProperty, object> propertyValues = contract.Properties.Where(p => !p.Ignored).ToDictionary(kv => kv, kv => (object)null); bool exit = false; do { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); if (!reader.Read()) { throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); } JsonProperty property; // attempt exact case match first // then try match ignoring case if (contract.Properties.TryGetClosestMatchProperty(memberName, out property)) { if (!property.Ignored) { Type memberType = ReflectionUtils.GetMemberUnderlyingType(property.Member); propertyValues[property] = CreateValue(reader, memberType, null, property.MemberConverter); } } else { if (_serializer.MissingMemberHandling == MissingMemberHandling.Error) { throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name)); } reader.Skip(); } break; case JsonToken.EndObject: exit = true; break; default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); } } while (!exit && reader.Read()); IDictionary <ParameterInfo, object> constructorParameters = c.GetParameters().ToDictionary(p => p, p => (object)null); IDictionary <JsonProperty, object> remainingPropertyValues = new Dictionary <JsonProperty, object>(); foreach (KeyValuePair <JsonProperty, object> propertyValue in propertyValues) { ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key; if (matchingConstructorParameter != null) { constructorParameters[matchingConstructorParameter] = propertyValue.Value; } else { remainingPropertyValues.Add(propertyValue); } } object createdObject = ReflectionUtils.CreateInstance(objectType, constructorParameters.Values.ToArray()); contract.InvokeOnDeserializing(createdObject); // go through unused values and set the newly created object's properties foreach (KeyValuePair <JsonProperty, object> remainingPropertyValue in remainingPropertyValues) { if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) { ReflectionUtils.SetMemberValue(remainingPropertyValue.Key.Member, createdObject, remainingPropertyValue.Value); } } contract.InvokeOnDeserialized(createdObject); return(createdObject); }
private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id) { contract.InvokeOnDeserializing(newObject); Dictionary <string, bool> requiredProperties = contract.Properties.Where(m => m.Required).ToDictionary(m => m.PropertyName, m => false); if (id != null) { Serializer.ReferenceResolver.AddReference(id, newObject); } int initialDepth = reader.Depth; do { switch (reader.TokenType) { case JsonToken.PropertyName: string memberName = reader.Value.ToString(); if (!reader.Read()) { throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); } // set required property even if null (matches WCF IsRequired behavour) SetRequiredProperty(memberName, requiredProperties); try { SetObjectMember(reader, newObject, contract, memberName); } catch (Exception ex) { if (IsErrorHandled(newObject, contract, memberName, ex)) { HandleError(reader, initialDepth); } else { throw; } } break; case JsonToken.EndObject: foreach (KeyValuePair <string, bool> requiredProperty in requiredProperties) { if (!requiredProperty.Value) { throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key)); } } contract.InvokeOnDeserialized(newObject); return(newObject); case JsonToken.Comment: // ignore break; default: throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType); } } while (reader.Read()); throw new JsonSerializationException("Unexpected end when deserializing object."); }