/// <summary> /// Update a specific key of this instance from a given JSON element internally /// </summary> /// <param name="key">Property name to update</param> /// <param name="jsonElement">Element to update this intance from</param> /// <param name="ignoreSbcProperties">Whether SBC properties are ignored</param> /// <param name="offset">Index offset</param> /// <param name="last">Whether this is the last update</param> /// <returns>Whether the key could be updated</returns> private bool InternalUpdateFromModel(string key, JsonElement jsonElement, bool ignoreSbcProperties, int offset = 0, bool last = true) { if (string.IsNullOrEmpty(key)) { UpdateFromJson(jsonElement, ignoreSbcProperties); return(true); } if (JsonProperties.TryGetValue(key, out PropertyInfo property)) { if (ignoreSbcProperties && Attribute.IsDefined(property, typeof(LinuxPropertyAttribute))) { // Skip this field if it must not be updated from RRF return(true); } if (property.PropertyType.IsSubclassOf(typeof(ModelObject))) { ModelObject value = (ModelObject)property.GetValue(this); value.UpdateFromJson(jsonElement, ignoreSbcProperties); return(true); } if (ModelCollection.GetItemType(property.PropertyType, out Type itemType)) { IList modelCollection = (IList)property.GetValue(this); if (ModelGrowingCollection.TypeMatches(property.PropertyType)) { ModelGrowingCollectionHelper.UpdateFromJson(modelCollection, itemType, jsonElement, ignoreSbcProperties); } else { ModelCollectionHelper.UpdateFromJson(modelCollection, itemType, jsonElement, ignoreSbcProperties, offset, last); } return(true); } if (property.PropertyType == typeof(ModelJsonDictionary)) { ModelJsonDictionary value = (ModelJsonDictionary)property.GetValue(this); value.UpdateFromJson(jsonElement); return(true); } #if VERIFY_OBJECT_MODEL Console.WriteLine("[warn] Missing key type handler for {0}", key); } else { Console.WriteLine("[warn] Missing property: {0} = {1}", key, jsonElement.GetRawText()); #endif } // Failed to find a property return(false); }
private object DeserializeJsonDictionaryObject(JsonDictionaryObject dictionaryObject) { var instance = Activator.CreateInstance(Type); foreach (var element in dictionaryObject.Elements) { JsonProperty jsonProperty; JsonProperties.TryGetValue(element.Key, out jsonProperty); if (jsonProperty == null) { continue; } if (jsonProperty.IsJsonObject) { jsonProperty.PropertyInfo.SetValue(instance, element.Value, null); continue; } if (jsonProperty.ObjectType == JsonObjectType.Runtime) { continue; } if (jsonProperty.ObjectType == JsonObjectType.Dictionary) { if (element.Value is JsonDictionaryObject) { var value = GetSerializer(jsonProperty.PropertyInfo.PropertyType).InternalDeserialize(element.Value); jsonProperty.PropertyInfo.SetValue(instance, value, null); } else if (element.Value is JsonValueObject && JsonEncoder.IsNullValue(element.Value)) { jsonProperty.PropertyInfo.SetValue(instance, null, null); } else { throw new Errors.JsonSerializeFailedException(element.Key, ".net runtime type does not match json type."); } } else if (jsonProperty.ObjectType == JsonObjectType.Collection) { if (element.Value is JsonCollectionObject) { var collectionObject = element.Value as JsonCollectionObject; jsonProperty.PropertyInfo.SetValue(instance, DeserializeJsonCollectionObject(collectionObject, jsonProperty.PropertyInfo.PropertyType), null); } else if (element.Value is JsonValueObject && JsonEncoder.IsNullValue(element.Value)) { jsonProperty.PropertyInfo.SetValue(instance, null, null); } else { throw new Errors.JsonSerializeFailedException(element.Key, ".net runtime type does not match json type."); } } else if (jsonProperty.ObjectType == JsonObjectType.Value && element.Value is JsonValueObject) { var value = DeserializeJsonPlainValueObject(element.Value as JsonValueObject, jsonProperty.PropertyInfo.PropertyType); jsonProperty.PropertyInfo.SetValue(instance, value, null); } else { throw new Errors.JsonSerializeFailedException(element.Key, ".net runtime type does not match json type."); } } return(instance); }