/// <summary> /// Returns info about the unleash setup. /// </summary> public override string ToString() { var sb = new StringBuilder("## Unleash settings ##"); sb.AppendLine($"Application name: {AppName}"); sb.AppendLine($"Environment: {Environment}"); sb.AppendLine($"Instance tag: {InstanceTag}"); sb.AppendLine($"Server Uri: {UnleashApi}"); sb.AppendLine($"Sdk version: {SdkVersion}"); sb.AppendLine($"Fetch toggles interval: {FetchTogglesInterval.TotalSeconds} seconds"); var metricsInterval = SendMetricsInterval.HasValue ? $"{SendMetricsInterval.Value.TotalSeconds} seconds" : "never"; sb.AppendLine($"Send metrics interval: {metricsInterval}"); sb.AppendLine($"Local storage folder: {LocalStorageFolder()}"); sb.AppendLine($"Backup file: {FeatureToggleFilename}"); sb.AppendLine($"Etag file: {EtagFilename}"); sb.AppendLine($"HttpClient Factory: {HttpClientFactory.GetType().Name}"); sb.AppendLine($"Json serializer: {JsonSerializer.GetType().Name}"); sb.AppendLine($"Context provider: {UnleashContextProvider.GetType().Name}"); return(sb.ToString()); }
public void ShouldDecodeMessageSuccessfully() { var decoded = new JsonSerializer().Decode <SessionData>(_jsonEncoded); Assert.AreEqual(typeof(SessionData), decoded.GetType()); Assert.AreEqual(decoded, _jsonStub); }
public void TheNonGenericFactoryMethodReturnsTheCorrectTypeOfSerializer() { var genericSerializer = new JsonSerializer<JsonSerializerFactoryTests>(); var interfaceSerializer = JsonSerializer.Create(typeof(JsonSerializerFactoryTests)); Assert.That(interfaceSerializer.GetType(), Is.EqualTo(genericSerializer.GetType())); }
public void TheNonGenericFactoryMethodReturnsTheCorrectTypeOfSerializer() { var genericSerializer = new JsonSerializer <JsonSerializerFactoryTests>(); var interfaceSerializer = JsonSerializer.Create(typeof(JsonSerializerFactoryTests)); Assert.That(interfaceSerializer.GetType(), Is.EqualTo(genericSerializer.GetType())); }
/// <summary> /// Creates and initializes a new instance of the ManateeJsonSerializer class. /// </summary> public ManateeSerializer() { _serializer = new JsonSerializer { Options = { EnumSerializationFormat = EnumSerializationFormat.AsName, FlagsEnumSeparator = "," } }; _method = _serializer.GetType().GetMethod("Serialize"); }
private static object ReadJsonBase(JsonSerializer serializer, TypeInfo type, JsonReader reader) { if (reader.TokenType == JsonToken.None) { reader.Read(); } var contract = serializer.ContractResolver.ResolveContract(type.AsType()); var getInternalSerializer = serializer.GetType().GetTypeInfo().GetDeclaredMethod("GetInternalSerializer"); var internalSerializer = getInternalSerializer.Invoke(serializer, new object[0]); var createValue = internalSerializer.GetType().GetTypeInfo().GetDeclaredMethod("CreateValueInternal"); var result = createValue.Invoke(internalSerializer, new object[] { reader, type, contract, null, null, null, null }); return(result); }
/// <summary> /// Creates and initializes a new instance of the ManateeJsonSerializer class. /// </summary> public ManateeSerializer() { _serializer = new JsonSerializer { Options = { EnumSerializationFormat = EnumSerializationFormat.AsName, FlagsEnumSeparator = "," } }; _serializer.CustomSerializations.RegisterType(DateTimeToJson, JsonToDateTime); InitializeAbstractionMap(_serializer); _method = _serializer.GetType().GetTypeInfo().DeclaredMethods .First(m => m.Name == "Serialize") .GetGenericMethodDefinition(); }
public T Deserialize <T>(IRestResponse response) { var result = Activator.CreateInstance <T>(); var events = result as List <Event>; if (events == null) { throw new InvalidOperationException("The type must be List<Event>."); } var json = JArray.Parse(response.Content); serializer = new JsonSerializer(); var deserializeMethod = serializer.GetType().GetMethods().First(m => m.IsGenericMethod && m.Name == "Deserialize"); var ns = typeof(Event).Namespace; var userType = typeof(User); var repositoryType = typeof(Repository); var userDeserializer = deserializeMethod.MakeGenericMethod(userType); var repoDeserializer = deserializeMethod.MakeGenericMethod(repositoryType); foreach (var eventData in json) { try { var payload = eventData.SelectToken("payload"); var eventDeserializer = deserializeMethod.MakeGenericMethod(Type.GetType(string.Format("{0}.{1}", ns, eventData["type"].Value <String>()))); var e = (Event)eventDeserializer.Invoke(serializer, new object[] { new JTokenReader(payload) }); e.Actor = (User)userDeserializer.Invoke(serializer, new object[] { new JTokenReader(eventData["actor"]) }); e.Public = eventData["public"].Value <bool?>(); e.CreatedAt = eventData["created_at"].Value <DateTime>(); e.Repo = (Repository)repoDeserializer.Invoke(serializer, new object[] { new JTokenReader(eventData["repo"]) }); events.Add(e); } catch (Exception) { // might silencly fail on an event } } return(result); }
public static void ApplyCustomSettings(this JsonSerializer serializer, JsonSerializerSettings settings) { if (settings == null) { return; } foreach (PropertyInfo prop in serializer.GetType().GetProperties()) { try { var value = settings.GetType().GetProperty(prop.Name).GetValue(settings); if (value == null) { continue; } prop.SetValue(serializer, value); } catch { } } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } if (objectType.IsAbstract) { JObject jo = JObject.Load(reader); Type boType; if (serializer.TypeNameHandling.HasFlag(TypeNameHandling.Objects) && jo.TryGetValue("$type", out JToken typeToken)) { boType = BusinessObjectSerializationBinder.BusinessObjectAndCOMTypes.SingleOrDefault(t => typeToken.Value <string>().ToUpper().StartsWith(t.FullName.ToUpper())); } else if (!jo.ContainsKey("boTyp")) { throw new ArgumentException("If deserializing into an abstract BusinessObject the key \"boTyp\" has to be set. But it wasn't."); } else { #pragma warning disable CS0618 // Type or member is obsolete boType = BoMapper.GetTypeForBoName(jo["boTyp"].Value <string>()); // ToDo: catch exception if boTyp is not set and throw exception with descriptive error message #pragma warning restore CS0618 // Type or member is obsolete } if (boType == null) { foreach (var assembley in AppDomain.CurrentDomain.GetAssemblies()) { try { boType = assembley.GetTypes().FirstOrDefault(x => x.Name.ToUpper() == jo["boTyp"].Value <string>().ToUpper()); } catch (ReflectionTypeLoadException) { continue; } if (boType != null) { break; } } if (boType == null) { throw new NotImplementedException($"The type '{jo["boTyp"].Value<string>()}' does not exist in the BO4E standard."); } } var deserializationMethod = serializer.GetType() // https://stackoverflow.com/a/5218492/10009545 .GetMethods() .Where(m => m.Name == nameof(serializer.Deserialize)) .Select(m => new { Method = m, Params = m.GetParameters(), Args = m.GetGenericArguments() }) .Where(x => x.Params.Length == 1 && x.Args.Length == 1) .Select(x => x.Method) .First() .GetGenericMethodDefinition() .MakeGenericMethod(new Type[] { boType }); try { return(deserializationMethod.Invoke(serializer, new object[] { jo.CreateReader() })); } catch (TargetInvocationException tie) when(tie.InnerException != null) { throw tie.InnerException; // to hide the reflection to the outside. } } else { serializer.ContractResolver.ResolveContract(objectType).Converter = null; return(serializer.Deserialize(JObject.Load(reader).CreateReader(), objectType)); } }
static JsonUtility() { serializer = new JsonSerializer { DateParseHandling = DateParseHandling.None, Converters = { new UtcDateTimeConverter() } }; serializableTypes = new HashSet <Type>(); // Register converters for types implementing IJsonSerializable or that have DataContract attributes // Include all types in ExoWeb and ExoRule automatically foreach (var converter in JsonConverter.Infer( typeof(ServiceHandler).Assembly.GetTypes().Union( typeof(Rule).Assembly.GetTypes().Where(type => typeof(Rule).IsAssignableFrom(type))))) { RegisterConverter(converter); } // Deserialize Value Change Event Func <JsonReader, ModelValueChangeEvent> deserializeValueChangeEvent = (reader) => { string p; ModelInstance instance = null; ModelValueProperty property = null; object oldValue = null; object newValue = null; while (reader.ReadProperty(out p)) { switch (p) { case "instance": instance = reader.ReadValue <ModelInstance>(); break; case "property": var propertyName = reader.ReadValue <string>(); property = (ModelValueProperty)instance.Type.Properties[propertyName]; if (property == null) { throw new SerializationException("Unable to deserialize ValueChange: property \"" + propertyName + "\" does not exist for type \"" + instance.Type.Name + "\"."); } break; case "oldValue": if (reader.TokenType == JsonToken.StartObject) { oldValue = reader.ReadValue(property.PropertyType); } else { oldValue = property.CoerceValue(reader.Value); reader.Read(); } break; case "newValue": if (reader.TokenType == JsonToken.StartObject) { newValue = reader.ReadValue(property.PropertyType); } else { newValue = property.CoerceValue(reader.Value); reader.Read(); } break; default: throw new ArgumentException("The specified property could not be deserialized.", p); } } return(new ModelValueChangeEvent(instance, property, oldValue, newValue)); }; // Deserialize Reference Change Event Func <JsonReader, ModelReferenceChangeEvent> deserializeReferenceChangeEvent = (reader) => { string p; ModelInstance instance = null; ModelReferenceProperty property = null; ModelInstance oldValue = null; ModelInstance newValue = null; while (reader.ReadProperty(out p)) { switch (p) { case "instance": instance = reader.ReadValue <ModelInstance>(); break; case "property": var propertyName = reader.ReadValue <string>(); property = (ModelReferenceProperty)instance.Type.Properties[propertyName]; if (property == null) { throw new SerializationException("Unable to deserialize ReferenceChange: property \"" + propertyName + "\" does not exist for type \"" + instance.Type.Name + "\"."); } break; case "oldValue": oldValue = reader.ReadValue <ModelInstance>(); break; case "newValue": newValue = reader.ReadValue <ModelInstance>(); break; default: throw new ArgumentException(@"The specified property could not be deserialized.", p); } } return(new ModelReferenceChangeEvent(instance, property, oldValue, newValue)); }; // Deserialize List Change Event Func <JsonReader, ModelListChangeEvent> deserializeListChangeEvent = (reader) => { string p; ModelInstance instance = null; ModelReferenceProperty property = null; ModelInstance[] added = null; ModelInstance[] removed = null; while (reader.ReadProperty(out p)) { switch (p) { case "instance": instance = reader.ReadValue <ModelInstance>(); break; case "property": var propertyName = reader.ReadValue <string>(); property = (ModelReferenceProperty)instance.Type.Properties[propertyName]; if (property == null) { throw new SerializationException("Unable to deserialize ListChange: property \"" + propertyName + "\" does not exist for type \"" + instance.Type.Name + "\"."); } break; case "added": added = reader.ReadValue <ModelInstance[]>(); break; case "removed": removed = reader.ReadValue <ModelInstance[]>(); break; default: throw new ArgumentException(@"The specified property could not be deserialized.", p); } } return(new ModelListChangeEvent(instance, property, added, removed)); }; // Deserialize Init New Event Func <JsonReader, ModelInitEvent.InitNew> deserializeInitNewEvent = (reader) => { string p; ModelInstance instance = null; while (reader.ReadProperty(out p)) { switch (p) { case "instance": instance = reader.ReadValue <ModelInstance>(); break; default: throw new ArgumentException(@"The specified property could not be deserialized.", p); } } return(new ModelInitEvent.InitNew(instance)); }; // Deserialize Init Existing Event Func <JsonReader, ModelInitEvent.InitExisting> deserializeInitExistingEvent = (reader) => { string p; ModelInstance instance = null; while (reader.ReadProperty(out p)) { switch (p) { case "instance": instance = reader.ReadValue <ModelInstance>(); break; default: throw new ArgumentException(@"The specified property could not be deserialized.", p); } } return(new ModelInitEvent.InitExisting(instance)); }; // Deserialize Delete Event Func <JsonReader, ModelDeleteEvent> deserializeDeleteEvent = (reader) => { string p; ModelInstance instance = null; bool isPendingDelete = false; while (reader.ReadProperty(out p)) { switch (p) { case "instance": instance = reader.ReadValue <ModelInstance>(); break; case "isPendingDelete": isPendingDelete = reader.ReadValue <bool>(); break; default: throw new ArgumentException(@"The specified property could not be deserialized.", p); } } return(new ModelDeleteEvent(instance, isPendingDelete)); }; // Construct Model Instance var createModelInstance = typeof(ModelInstance).GetConstructor( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(ModelType), typeof(string) }, null); // Register custom converters for ModelType, ModelProperty, ModelMethod, ModelInstance, ModelEvent foreach (var converter in new JsonConverter[] { // Model Type new JsonConverter <ModelType>( (modelType, json) => { // Base Type if (modelType.BaseType != null) { json.Set("baseType", JsonConverter.GetJsonReferenceType(modelType.BaseType)); } // Base Type if (!String.IsNullOrEmpty(modelType.Format)) { json.Set("format", modelType.Format); } // Properties if (modelType.Properties.Any()) { json.Set("properties", modelType.Properties .Where(property => property.DeclaringType == modelType && ExoWeb.IncludeInClientModel(property)) .ToDictionary(property => property.Name)); } // Methods if (modelType.Methods.Any()) { json.Set("methods", modelType.Methods.ToDictionary(method => method.Name)); } // Rules var rules = Rule.GetRegisteredRules(modelType).ToList(); var typeRules = rules.Where(rule => (rule.ExecutionLocation & RuleExecutionLocation.Client) > 0 && !(rule is IPropertyRule)).ToArray(); if (typeRules.Any()) { json.Set("rules", typeRules); } // Condition Types var serverConditionTypes = rules .Where(rule => (rule.ExecutionLocation & RuleExecutionLocation.Client) == 0) .SelectMany(rule => rule.ConditionTypes) .ToArray(); if (serverConditionTypes.Any()) { json.Set("conditionTypes", serverConditionTypes); } // Exports var exports = json.Global <Dictionary <string, string> >("exports"); if (exports.Any()) { json.Set("exports", json.Global <Dictionary <string, string> >("exports")); } }, json => { throw new NotSupportedException("ModelType cannot be deserialized."); }), // Model Property new JsonConverter <ModelProperty>( (property, json) => { // Type string type = (property is ModelValueProperty ? JsonConverter.GetJsonValueType(((ModelValueProperty)property).PropertyType) ?? "Object" : JsonConverter.GetJsonReferenceType(((ModelReferenceProperty)property).PropertyType)) + (property.IsList ? "[]" : ""); json.Set("type", type); // IsStatic if (property.IsStatic) { json.Set("isStatic", true); } // IsPersisted if (!property.IsPersisted && !property.IsStatic) { json.Set("isPersisted", false); } // IsCalculated if (property.IsCalculated) { json.Set("isCalculated", true); } // Index int index = 0; foreach (ModelProperty p in property.DeclaringType.Properties) { if (p == property) { break; } if (ExoWeb.IncludeInClientModel(p) && !p.IsStatic) { index++; } } if (!property.IsStatic) { json.Set("index", index); } // Format string format = property.Format; if (!string.IsNullOrEmpty(format)) { json.Set("format", format); } // Label string label = property.Label; if (!string.IsNullOrEmpty(label)) { json.Set("label", label); } // Help Text string helptext = property.HelpText; if (!string.IsNullOrEmpty(helptext)) { json.Set("helptext", helptext); } // Rules var rules = Rule .GetRegisteredRules(property.DeclaringType) .Where(rule => (rule.ExecutionLocation & RuleExecutionLocation.Client) > 0 && rule is IPropertyRule && rule.RootType.Properties[((IPropertyRule)rule).Property] == property) .ToDictionary(rule => rule is ICalculationRule ? "calculated" : String.Format("{0}.{1}.{2}", rule.RootType.Name, ((IPropertyRule)rule).Property, ((IPropertyRule)rule).Name) == rule.Name ? ((IPropertyRule)rule).Name.Substring(0, 1).ToLower() + ((IPropertyRule)rule).Name.Substring(1) : rule.Name); if (rules.Any()) { json.Set("rules", rules); } // Default Value if (property is ModelValueProperty) { var defaultValue = ((ModelValueProperty)property).DefaultValue; if (defaultValue != null) { json.Set("defaultValue", ((ModelValueProperty)property).DefaultValue); } } }, json => { throw new NotSupportedException("ModelProperty cannot be deserialized."); }), // Model Method new JsonConverter <ModelMethod>( (method, json) => { // Parameters json.Set("parameters", method.Parameters.Select(p => p.Name)); // IsStatic json.Set("isStatic", method.IsStatic); }, json => { throw new NotSupportedException("ModelMethod cannot be deserialized."); }), // Model Instance new JsonConverter <ModelInstance>( (instance, json) => { json.Set("id", instance.Id); json.Set("type", instance.Type.Name); }, reader => { string p; ModelType type = null; string id = null; while (reader.ReadProperty(out p)) { switch (p) { case "type": type = ModelContext.Current.GetModelType(reader.ReadValue <string>()); break; case "id": id = reader.ReadValue <string>(); break; // Ignore case "isNew": reader.ReadValue <bool>(); break; default: throw new ArgumentException(@"The specified property could not be deserialized.", p); } } return((ModelInstance)createModelInstance.Invoke(new object[] { type, id })); }), // Model Event new JsonConverter <ModelEvent>( (modelEvent, json) => { throw new NotSupportedException("ModelEvent cannot be deserialized."); }, (reader) => { string p; if (reader.ReadProperty(out p) && p == "type") { string eventName = reader.ReadValue <string>(); switch (eventName) { case "ValueChange": return(deserializeValueChangeEvent(reader)); case "ReferenceChange": return(deserializeReferenceChangeEvent(reader)); case "ListChange": return(deserializeListChangeEvent(reader)); case "InitNew": return(deserializeInitNewEvent(reader)); case "InitExisting": return(deserializeInitExistingEvent(reader)); case "Delete": return(deserializeDeleteEvent(reader)); } throw new NotSupportedException(eventName + " event cannot be deserialized."); } else { throw new FormatException("The type parameter 'type' must be the first serialized value in model event json."); } }), // Model Value Change Event new JsonConverter <ModelValueChangeEvent>( (modelEvent, json) => { //Property sequence matters json.Set("type", "ValueChange"); json.Set("instance", GetEventInstance(modelEvent.Instance, modelEvent.InstanceId)); json.Set("property", modelEvent.Property.Name); json.Set("oldValue", modelEvent.OldValue); json.Set("newValue", modelEvent.NewValue); }, deserializeValueChangeEvent), // Model Reference Change Event new JsonConverter <ModelReferenceChangeEvent>( (modelEvent, json) => { json.Set("type", "ReferenceChange"); json.Set("instance", GetEventInstance(modelEvent.Instance, modelEvent.InstanceId)); json.Set("property", modelEvent.Property.Name); json.Set("oldValue", GetEventInstance(modelEvent.OldValue, modelEvent.OldValueId)); json.Set("newValue", GetEventInstance(modelEvent.NewValue, modelEvent.NewValueId)); }, deserializeReferenceChangeEvent), // Model List Change Event new JsonConverter <ModelListChangeEvent>( (modelEvent, json) => { json.Set("type", "ListChange"); json.Set("instance", GetEventInstance(modelEvent.Instance, modelEvent.InstanceId)); json.Set("property", modelEvent.Property.Name); json.Set("added", modelEvent.Added.Select((instance, index) => GetEventInstance(instance, modelEvent.AddedIds.ElementAt(index)))); json.Set("removed", modelEvent.Removed.Select((instance, index) => GetEventInstance(instance, modelEvent.RemovedIds.ElementAt(index)))); }, deserializeListChangeEvent), // Model Init New Event new JsonConverter <ModelInitEvent.InitNew>( (modelEvent, json) => { json.Set("type", "InitNew"); json.Set("instance", GetEventInstance(modelEvent.Instance, modelEvent.InstanceId)); }, deserializeInitNewEvent), // Model Init Existing Event new JsonConverter <ModelInitEvent.InitExisting>( (modelEvent, json) => { json.Set("type", "InitExisting"); json.Set("instance", GetEventInstance(modelEvent.Instance, modelEvent.InstanceId)); }, deserializeInitExistingEvent), // Model Delete Event new JsonConverter <ModelDeleteEvent>( (modelEvent, json) => { json.Set("type", "Delete"); json.Set("instance", GetEventInstance(modelEvent.Instance, modelEvent.InstanceId)); json.Set("isPendingDelete", modelEvent.IsPendingDelete); }, deserializeDeleteEvent), // Model Save Event new JsonConverter <ModelSaveEvent>( (modelEvent, json) => { json.Set("type", "Save"); json.Set("instance", GetEventInstance(modelEvent.Instance, modelEvent.InstanceId)); json.Set("added", modelEvent.Added.Select(instance => new Dictionary <string, string>() { { "type", instance.Type.Name }, { "oldId", instance.OriginalId }, { "newId", instance.Id } })); json.Set("modified", modelEvent.Modified); json.Set("deleted", modelEvent.Deleted); }, json => { throw new NotSupportedException("ModelSaveEvent cannot be deserialized."); }), // Condition Type new JsonConverter <ConditionType>( (conditionType, json) => { json.Set("code", conditionType.Code); json.Set("category", conditionType.Category.ToString()); if (conditionType.Sets != null && conditionType.Sets.Any()) { json.Set("sets", conditionType.Sets.Select(set => set.Name)); } json.Set("message", conditionType.Message); }, json => { throw new NotSupportedException("ConditionType cannot be deserialized."); }), // Condition new JsonConverter <Condition>( (condition, json) => { if (condition.Message != condition.Type.Message) { json.Set("message", condition.Message); } json.Set("targets", condition.Targets.Where(ct => ct.Target != null)); }, json => { throw new NotSupportedException("Condition cannot be deserialized."); }), // Condition Target new JsonConverter <ConditionTarget>( (conditionTarget, json) => { json.Set("instance", conditionTarget.Target); json.Set("properties", conditionTarget.Properties); }, json => { throw new NotSupportedException("ConditionTarget cannot be deserialized."); }), // Rule new JsonConverter <Rule>( (rule, json) => { if (rule is ICalculationRule) { var calculation = (ICalculationRule)rule; json.Set("onChangeOf", calculation.Predicates); if (rule is IClientCalculationRule) { var clientCalc = (IClientCalculationRule)rule; json.Set("calculate", clientCalc.FunctionBody); foreach (var export in clientCalc.Exports) { json.Global <Dictionary <string, string> >("exports")[export.Key] = export.Value; } } else { json.Set("calculate", calculation.Calculation); } } else if (rule is IConditionRule) { var condition = (IConditionRule)rule; json.Set("type", "condition"); json.Set("properties", condition.Properties); json.Set("onChangeOf", condition.Predicates); json.Set("conditionType", condition.ConditionType); json.Set("assert", condition.Condition); } else { throw new NotSupportedException("Rules of type " + rule.GetType().FullName + " cannot be serialized. Call ExoWeb.RegisterConverters() to register a converter to support serializing rules of this type."); } }, json => { throw new NotSupportedException("Rule cannot be deserialized."); }), // AllowedValuesRule new JsonConverter <AllowedValuesRule>( (rule, json) => { SerializePropertyRule(rule, json); var sourceExpression = rule.SourceExpression; if (sourceExpression != null) { json.Set("fn", sourceExpression.Expression); if (!String.IsNullOrEmpty(rule.Path)) { json.Set("onChangeOf", new string[] { rule.Path }); } } else { json.Set("source", rule.Source); } if (rule.IgnoreValidation) { json.Set("ignoreValidation", rule.IgnoreValidation); } }, json => { throw new NotSupportedException("AllowedValuesRule cannot be deserialized."); }), // CompareRule new JsonConverter <CompareRule>( (rule, json) => { SerializePropertyRule(rule, json); json.Set("compareOperator", rule.CompareOperator.ToString()); json.Set("compareSource", rule.CompareSource); }, json => { throw new NotSupportedException("CompareRule cannot be deserialized."); }), // ListLengthRule new JsonConverter <ListLengthRule>( (rule, json) => { SerializePropertyRule(rule, json); // Min if (rule.MinExpression != null) { json.Set("minFn", rule.MinExpression.Expression); } else { json.Set("min", rule.Minimum); } // Max if (rule.MaxExpression != null) { json.Set("maxFn", rule.MaxExpression.Expression); } else { json.Set("max", rule.Maximum); } // OnChangeOf if (!String.IsNullOrEmpty(rule.Path)) { json.Set("onChangeOf", new string[] { rule.Path }); } }, json => { throw new NotSupportedException("ListLengthRule cannot be deserialized."); }), // RangeRule new JsonConverter <RangeRule>( (rule, json) => { SerializePropertyRule(rule, json); // Min if (rule.MinExpression != null) { json.Set("minFn", rule.MinExpression.Expression); } else { json.Set("min", rule.Minimum); } // Max if (rule.MaxExpression != null) { json.Set("maxFn", rule.MaxExpression.Expression); } else { json.Set("max", rule.Maximum); } // OnChangeOf if (!String.IsNullOrEmpty(rule.Path)) { json.Set("onChangeOf", new string[] { rule.Path }); } }, json => { throw new NotSupportedException("RangeRule cannot be deserialized."); }), // ValidationRule new JsonConverter <ValidationRule>( (rule, json) => { SerializePropertyRule(rule, json); // Validation json.Set("isError", rule.ValidationExpression.Expression); // ErrorMessage if (rule.ErrorMessageResource != null) { json.Set("message", rule.ErrorMessageResource); } else { json.Set("message", rule.ErrorMessageExpression.Expression); } json.Set("properties", rule.AdditionalTargets); // OnChangeOf if (!String.IsNullOrEmpty(rule.Path)) { json.Set("onChangeOf", new string[] { rule.Path }); } }, json => { throw new NotSupportedException("ValidationRule cannot be deserialized."); }), // RequiredRule new JsonConverter <RequiredRule>( (rule, json) => { SerializePropertyRule(rule, json); if (rule.RequiredValue != null) { json.Set("requiredValue", rule.RequiredValue); } }, json => { throw new NotSupportedException("RequiredRule cannot be deserialized."); }), // RequiredIfRule new JsonConverter <RequiredIfRule>( (rule, json) => { SerializePropertyRule(rule, json); if (rule.RequiredExpression != null) { json.Set("fn", rule.RequiredExpression.Expression); // OnChangeOf if (!String.IsNullOrEmpty(rule.Path)) { json.Set("onChangeOf", new string[] { rule.Path }); } } else { json.Set("compareOperator", rule.CompareOperator.ToString()); json.Set("compareSource", rule.CompareSource); json.Set("compareValue", rule.CompareValue); } if (rule.RequiredValue != null) { json.Set("requiredValue", rule.RequiredValue); } }, json => { throw new NotSupportedException("RequiredIfRule cannot be deserialized."); }), // OwnerRule new JsonConverter <OwnerRule>( (rule, json) => SerializePropertyRule(rule, json), json => { throw new NotSupportedException("OwnerRule cannot be deserialized."); }), // StringLengthRule new JsonConverter <StringLengthRule>( (rule, json) => { SerializePropertyRule(rule, json); if (rule.Minimum > 0) { json.Set("min", rule.Minimum); } if (rule.Maximum > 0) { json.Set("max", rule.Maximum); } }, json => { throw new NotSupportedException("StringLengthRule cannot be deserialized."); }), // StringFormatRule new JsonConverter <StringFormatRule>( (rule, json) => { SerializePropertyRule(rule, json); if (!String.IsNullOrEmpty(rule.FormatDescription)) { json.Set("description", rule.FormatDescription); } json.Set("expression", rule.FormatExpression.ToString()); if (!String.IsNullOrEmpty(rule.ReformatExpression)) { json.Set("reformat", rule.ReformatExpression); } }, json => { throw new NotSupportedException("StringFormatRule cannot be deserialized."); }), }) { JsonUtility.RegisterConverter(converter); } // Cache the method info of the deserialize method // The non-generic version of this method was added in .NET 4.0 deserialize = serializer.GetType().GetMethod("Deserialize", new Type[] { typeof(string) }); }