public override object?ReadJson(JsonReader reader, Type objectType, object?existingValue, JsonSerializer serializer) { using (HeavyProfiler.LogNoStackTrace("ReadJson", () => objectType.Name)) { if (reader.TokenType == JsonToken.Null) { return(null); } using (EntityCache ec = new EntityCache()) { reader.Assert(JsonToken.StartObject); ModifiableEntity mod = GetEntity(reader, objectType, existingValue, out bool markedAsModified); var pr = GetCurrentPropertyRoute(mod); var dic = PropertyConverter.GetPropertyConverters(mod.GetType()); using (JsonSerializerExtensions.SetAllowDirectMListChanges(markedAsModified)) while (reader.TokenType == JsonToken.PropertyName) { if ((string)reader.Value ! == "mixins") { var entity = (Entity)mod; reader.Read(); reader.Assert(JsonToken.StartObject); reader.Read(); while (reader.TokenType == JsonToken.PropertyName) { var mixin = entity[(string)reader.Value !];
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } using (EntityCache ec = new EntityCache()) { reader.Assert(JsonToken.StartObject); ModifiableEntity mod = GetEntity(reader, objectType, existingValue, serializer, out bool markedAsModified); var pr = GetCurrentPropertyRoute(mod); var dic = PropertyConverter.GetPropertyConverters(mod.GetType()); while (reader.TokenType == JsonToken.PropertyName) { if ((string)reader.Value == "mixins") { var entity = (Entity)mod; reader.Read(); reader.Assert(JsonToken.StartObject); reader.Read(); while (reader.TokenType == JsonToken.PropertyName) { var mixin = entity[(string)reader.Value]; reader.Read(); using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr.Add(mixin.GetType()))) serializer.DeserializeValue(reader, mixin.GetType(), mixin); reader.Read(); } reader.Assert(JsonToken.EndObject); reader.Read(); } else { PropertyConverter pc = dic.GetOrThrow((string)reader.Value); reader.Read(); ReadJsonProperty(reader, serializer, mod, pc, pr, markedAsModified); reader.Read(); } } reader.Assert(JsonToken.EndObject); AfterDeserilization.Invoke(mod); return(mod); } }
public ReadJsonPropertyContext(JsonReader jsonReader, JsonSerializer jsonSerializer, PropertyConverter propertyConverter, ModifiableEntity entity, PropertyRoute parentPropertyRoute) { JsonReader = jsonReader; JsonSerializer = jsonSerializer; PropertyConverter = propertyConverter; Entity = entity; ParentPropertyRoute = parentPropertyRoute; }
public WriteJsonPropertyContext(ModifiableEntity entity, string lowerCaseName, PropertyConverter propertyConverter, PropertyRoute parentPropertyRoute, JsonWriter jsonWriter, JsonSerializer jsonSerializer) { Entity = entity; LowerCaseName = lowerCaseName; PropertyConverter = propertyConverter; ParentPropertyRoute = parentPropertyRoute; JsonWriter = jsonWriter; JsonSerializer = jsonSerializer; }
private bool ValidateModifiableEntity(ValidationContext validationContext, ModifiableEntity mod) { bool isValid = true; PropertyScope propertyScope = new PropertyScope(); validationContext.KeyBuilders.Push(propertyScope); var entity = mod as Entity; using (entity == null ? null : entity.Mixins.OfType <CorruptMixin>().Any(c => c.Corrupt) ? Corruption.AllowScope() : Corruption.DenyScope()) { foreach (var kvp in PropertyConverter.GetPropertyConverters(mod.GetType())) { if (kvp.Value.AvoidValidate) { continue; } propertyScope.PropertyName = kvp.Key; if (SignumValidate(validationContext, kvp.Value.GetValue(mod)) ?? true) { isValid = false; } string error = kvp.Value.PropertyValidator.PropertyCheck(mod); if (error != null) { string key = CalculateKey(validationContext); if (validationContext.ModelState.IsValidField(key)) { isValid = false; validationContext.ModelState.AddModelError(key, error); } } } } if (entity != null && entity.Mixins.Any()) { propertyScope.PropertyName = "mixins"; PropertyScope mixinScope = new PropertyScope(); validationContext.KeyBuilders.Push(mixinScope); foreach (var mixin in entity.Mixins) { mixinScope.PropertyName = mixin.GetType().Name; if (!ValidateModifiableEntity(validationContext, mixin)) { isValid = false; } } validationContext.KeyBuilders.Pop(); } validationContext.KeyBuilders.Pop(); return(isValid); }
private bool ValidateModifiableEntity(ModifiableEntity mod) { using (Validator.ModelBinderScope()) { bool isValid = true; var entity = mod as Entity; using (entity == null ? null : entity.Mixins.OfType <CorruptMixin>().Any(c => c.Corrupt) ? Corruption.AllowScope() : Corruption.DenyScope()) { foreach (var kvp in PropertyConverter.GetPropertyConverters(mod.GetType())) { if (kvp.Value.AvoidValidate) { continue; } string error = kvp.Value.PropertyValidator.PropertyCheck(mod); if (error != null) { isValid = false; ModelState.AddModelError(this.Key + "." + kvp.Key, error); } var val = kvp.Value.GetValue(mod); if (this.CurrentPath.Push(val)) { using (StateManager.Recurse(this, this.Key + "." + kvp.Key, null, val, null)) { if (this.SignumValidate() == false) { isValid = false; } } } } } if (entity != null && entity.Mixins.Any()) { foreach (var mixin in entity.Mixins) { if (this.CurrentPath.Push(mixin)) { using (StateManager.Recurse(this, "mixins[" + mixin.GetType().Name + "].element", null, mixin, null)) { isValid &= ValidateModifiableEntity(mixin); } } } } return(isValid); } }
public void ReadJsonProperty(JsonReader reader, JsonSerializer serializer, ModifiableEntity entity, PropertyConverter pc, PropertyRoute parentRoute, bool markedAsModified) { if (pc.CustomReadJsonProperty != null) { pc.CustomReadJsonProperty(new ReadJsonPropertyContext { JsonReader = reader, JsonSerializer = serializer, Entity = entity, ParentPropertyRoute = parentRoute, PropertyConverter = pc, }); } else { object oldValue = pc.GetValue(entity); var pi = pc.PropertyValidator.PropertyInfo; var pr = parentRoute.Add(pi); using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr)) { object newValue = serializer.DeserializeValue(reader, pi.PropertyType, oldValue); if (!IsEquals(newValue, oldValue)) { if (!markedAsModified && parentRoute.RootType.IsEntity()) { try { //Call attention of developer throw new InvalidOperationException($"'modified' is not set but '{pi.Name}' is modified"); } catch (Exception) { } } else { AssertCanWrite(pr); if (newValue == null && pc.IsNotNull()) //JSON.Net already complaining { return; } pc.SetValue?.Invoke(entity, newValue); } } } } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } using (EntityCache ec = new EntityCache()) { reader.Assert(JsonToken.StartObject); bool markedAsModified; ModifiableEntity mod = GetEntity(reader, objectType, existingValue, serializer, out markedAsModified); var pr = JsonSerializerExtensions.CurrentPropertyRoute; if (pr == null || mod is IRootEntity) { pr = PropertyRoute.Root(mod.GetType()); } else if (pr.Type.ElementType() == objectType) { pr = pr.Add("Item"); //Because we have a custom MListJsonConverter but not for other simpler collections } var dic = PropertyConverter.GetPropertyConverters(mod.GetType()); while (reader.TokenType == JsonToken.PropertyName) { if ((string)reader.Value == "mixins") { var entity = (Entity)mod; reader.Read(); reader.Assert(JsonToken.StartObject); reader.Read(); while (reader.TokenType == JsonToken.PropertyName) { var mixin = entity[(string)reader.Value]; reader.Read(); using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr.Add(mixin.GetType()))) serializer.DeserializeValue(reader, mixin.GetType(), mixin); reader.Read(); } reader.Assert(JsonToken.EndObject); reader.Read(); } else { PropertyConverter pc = dic.GetOrThrow((string)reader.Value); reader.Read(); ReadJsonProperty(reader, serializer, mod, pc, pr, markedAsModified); reader.Read(); } } reader.Assert(JsonToken.EndObject); AfterDeserilization.Invoke(mod); return(mod); } }
public void WriteJsonProperty(JsonWriter writer, JsonSerializer serializer, ModifiableEntity mod, string lowerCaseName, PropertyConverter pc, PropertyRoute route) { if (pc.CustomWriteJsonProperty != null) { pc.CustomWriteJsonProperty(new WriteJsonPropertyContext { JsonWriter = writer, JsonSerializer = serializer, LowerCaseName = lowerCaseName, Entity = mod, ParentPropertyRoute = route, PropertyConverter = pc }); } else { var pr = route.Add(pc.PropertyValidator.PropertyInfo); string error = CanReadPropertyRoute?.Invoke(pr); if (error != null) { return; } using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr)) { writer.WritePropertyName(lowerCaseName); serializer.Serialize(writer, pc.GetValue(mod)); } } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var pr = JsonSerializerExtensions.CurrentPropertyRoute; if (pr == null || typeof(IRootEntity).IsAssignableFrom(pr.Type)) { pr = PropertyRoute.Root(value.GetType()); } else if (pr.Type.ElementType() == value.GetType()) { pr = pr.Add("Item"); } ModifiableEntity mod = (ModifiableEntity)value; writer.WriteStartObject(); var entity = mod as Entity; if (entity != null) { writer.WritePropertyName("Type"); writer.WriteValue(TypeLogic.TryGetCleanName(mod.GetType())); writer.WritePropertyName("id"); writer.WriteValue(entity.IdOrNull == null ? null : entity.Id.Object); if (entity.IsNew) { writer.WritePropertyName("isNew"); writer.WriteValue(true); } if (Schema.Current.Table(entity.GetType()).Ticks != null) { writer.WritePropertyName("ticks"); writer.WriteValue(entity.Ticks.ToString()); } } else { writer.WritePropertyName("Type"); writer.WriteValue(mod.GetType().Name); } if (!(mod is MixinEntity)) { writer.WritePropertyName("toStr"); writer.WriteValue(mod.ToString()); } writer.WritePropertyName("modified"); writer.WriteValue(mod.Modified == ModifiedState.Modified || mod.Modified == ModifiedState.SelfModified); foreach (var kvp in PropertyConverter.GetPropertyConverters(value.GetType())) { WriteJsonProperty(writer, serializer, mod, kvp.Key, kvp.Value, pr); } if (entity != null && entity.Mixins.Any()) { writer.WritePropertyName("mixins"); writer.WriteStartObject(); foreach (var m in entity.Mixins) { var prm = pr.Add(m.GetType()); using (JsonSerializerExtensions.SetCurrentPropertyRoute(prm)) { writer.WritePropertyName(m.GetType().Name); serializer.Serialize(writer, m); } } writer.WriteEndObject(); } writer.WriteEndObject(); }
public void WriteJsonProperty(JsonWriter writer, JsonSerializer serializer, ModifiableEntity mod, string lowerCaseName, PropertyConverter pc, PropertyRoute route) { if (pc.CustomWriteJsonProperty != null) { pc.CustomWriteJsonProperty(new WriteJsonPropertyContext { JsonWriter = writer, JsonSerializer = serializer, LowerCaseName = lowerCaseName, Entity = mod, ParentPropertyRoute = route, PropertyConverter = pc }); } else { var pr = route.Add(pc.PropertyValidator.PropertyInfo); string error = CanReadPropertyRoute?.Invoke(pr); if (error != null) { return; } using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr)) { writer.WritePropertyName(lowerCaseName); serializer.Serialize(writer, pc.GetValue(mod)); if (writer.WriteState == WriteState.Property) { throw new InvalidOperationException($"Impossible to serialize '{mod}' to JSON. Maybe there is a cycle?"); } } } }
public void WriteJsonProperty(JsonWriter writer, JsonSerializer serializer, ModifiableEntity mod, string lowerCaseName, PropertyConverter pc, PropertyRoute route) { if (pc.CustomWriteJsonProperty != null) { pc.CustomWriteJsonProperty(new WriteJsonPropertyContext( entity: mod, lowerCaseName: lowerCaseName, propertyConverter: pc, parentPropertyRoute: route, jsonWriter: writer, jsonSerializer: serializer )); } else { var pr = route.Add(pc.PropertyValidator !.PropertyInfo); string?error = CanReadPropertyRoute?.Invoke(pr); if (error != null) { return; } using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr)) { writer.WritePropertyName(lowerCaseName); var val = pc.GetValue !(mod); if (val is Lite <Entity> lite) { new LiteJsonConverter().WriteJson(writer, lite, serializer); } else { serializer.Serialize(writer, pc.GetValue(mod)); } if (writer.WriteState == WriteState.Property) { throw new InvalidOperationException($"Impossible to serialize '{mod}' to JSON. Maybe there is a cycle?"); } } } }
public void ReadJsonProperty(JsonReader reader, JsonSerializer serializer, ModifiableEntity entity, PropertyConverter pc, PropertyRoute parentRoute, bool markedAsModified) { if (pc.CustomReadJsonProperty != null) { pc.CustomReadJsonProperty(new ReadJsonPropertyContext { JsonReader = reader, JsonSerializer = serializer, Entity = entity, ParentPropertyRoute = parentRoute, PropertyConverter = pc, }); } else { object oldValue = pc.GetValue(entity); var pi = pc.PropertyValidator.PropertyInfo; var pr = parentRoute.Add(pi); using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr)) { object newValue = serializer.DeserializeValue(reader, pi.PropertyType, oldValue); if (!IsEquals(newValue, oldValue)) { if (!markedAsModified && parentRoute.RootType.IsEntity()) { try { //Call attention of developer throw new InvalidOperationException($"'modified' is not set but '{pi.Name}' is modified"); } catch (Exception) { } } else { AssertCanWrite(pr); if (newValue == null && pc.IsNotNull()) //JSON.Net already complaining return; pc.SetValue?.Invoke(entity, newValue); } } } } }
public void WriteJsonProperty(JsonWriter writer, JsonSerializer serializer, ModifiableEntity mod, string lowerCaseName, PropertyConverter pc, PropertyRoute route) { if (pc.CustomWriteJsonProperty != null) { pc.CustomWriteJsonProperty(new WriteJsonPropertyContext { JsonWriter = writer, JsonSerializer = serializer, LowerCaseName = lowerCaseName, Entity = mod, ParentPropertyRoute = route, PropertyConverter = pc }); } else { var pr = route.Add(pc.PropertyValidator.PropertyInfo); string error = CanReadPropertyRoute?.Invoke(pr); if (error != null) return; using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr)) { writer.WritePropertyName(lowerCaseName); serializer.Serialize(writer, pc.GetValue(mod)); } } }
public void ReadJsonProperty(JsonReader reader, JsonSerializer serializer, ModifiableEntity entity, PropertyConverter pc, PropertyRoute parentRoute, bool markedAsModified) { if (pc.CustomReadJsonProperty != null) { pc.CustomReadJsonProperty(new ReadJsonPropertyContext( jsonReader: reader, jsonSerializer: serializer, entity: entity, parentPropertyRoute: parentRoute, propertyConverter: pc )); } else { object?oldValue = pc.GetValue !(entity); var pi = pc.PropertyValidator !.PropertyInfo; var pr = parentRoute.Add(pi); using (JsonSerializerExtensions.SetCurrentPropertyRoute(pr)) { object newValue = serializer.DeserializeValue(reader, pi.PropertyType.Nullify(), oldValue); if (!IsEquals(newValue, oldValue)) { if (!markedAsModified && parentRoute.RootType.IsEntity()) { if (!pi.HasAttribute <IgnoreAttribute>()) { try { //Call attention of developer throw new InvalidOperationException($"'modified' is not set but '{pi.Name}' is modified"); } catch (Exception) { } } } else { AssertCanWrite(pr); if (newValue == null && pc.IsNotNull()) { entity.SetTemporalError(pi, ValidationMessage._0IsNotSet.NiceToString(pi.NiceName())); return; } pc.SetValue?.Invoke(entity, newValue); } } } } }