public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var result = new ZoneProgramInput(); // Deserialize into a temporary JObject JObject obj = serializer.Deserialize <JObject>(reader); // Populate the ZoneProgramInput object with the contents serializer.Populate(obj.CreateReader(), result); // Overwrite the "Value" property with the correct value based on the // "Type" property. result.SetValue(obj.GetValue("value", StringComparison.OrdinalIgnoreCase) .ToObject(result.Type, serializer)); return(result); }
/// <summary> /// Adds a live input as a direct map to a member of the subclass. This essentially extends a property in /// the subclass as an input, which can be set to any value by the user. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="instance"></param> /// <param name="propertyName"></param> /// <param name="filterPredicate">The incoming value will be run through this filter predicate function and only set the value if the function returns true.</param> /// <returns></returns> protected ZoneProgramInput AddMappedInput <T>(object instance, string propertyName, Func <T, bool> filterPredicate = null) { var propertyInfo = instance.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var input = new ZoneProgramInput(propertyInfo.Name, propertyInfo.PropertyType); Inputs.Add(input); if (filterPredicate != null) { input.Subscribe(incomingValue => { if (filterPredicate(ConvertIncomingValue <T>(incomingValue))) { propertyInfo.SetValue(instance, incomingValue); } else { throw new WarningException("Incoming value out of range of valid input values."); } }); } else { input.Subscribe(incomingValue => { if (propertyInfo.CanWrite) { propertyInfo.SetValue(instance, ConvertIncomingValue <T>(incomingValue)); } else { throw new InvalidOperationException( $"Input {input.Name} has an underlying property without an accessible setter. Cannot set value for this property."); } }); } //set value of input to the value of the property input.SetValue(propertyInfo.GetValue(instance)); return(input); }