using System.Text.Json; using Microsoft.Extensions.Options; namespace CrupestApi.Commons.Crud; /// /// Contains all you need to do with json. /// public class EntityJsonHelper where TEntity : class { private readonly TableInfo _table; private readonly IOptionsMonitor _jsonSerializerOptions; public EntityJsonHelper(TableInfoFactory tableInfoFactory, IOptionsMonitor jsonSerializerOptions) { _table = tableInfoFactory.Get(typeof(TEntity)); _jsonSerializerOptions = jsonSerializerOptions; } public Dictionary ConvertEntityToDictionary(TEntity entity, bool includeNonColumnProperties = false) { var result = new Dictionary(); foreach (var column in _table.PropertyColumns) { var value = column.PropertyInfo!.GetValue(entity); var realValue = column.ColumnType.ConvertToDatabase(value); result[column.ColumnName] = realValue; } if (includeNonColumnProperties) { foreach (var propertyInfo in _table.NonColumnProperties) { var value = propertyInfo.GetValue(entity); result[propertyInfo.Name] = value; } } return result; } public string ConvertEntityToJson(TEntity entity, bool includeNonColumnProperties = false) { var dictionary = ConvertEntityToDictionary(entity, includeNonColumnProperties); return JsonSerializer.Serialize(dictionary, _jsonSerializerOptions.CurrentValue); } public TEntity ConvertJsonToEntityForInsert(JsonElement jsonElement) { if (jsonElement.ValueKind is not JsonValueKind.Object) throw new ArgumentException("The jsonElement must be an object."); var result = Activator.CreateInstance(); foreach (var column in _table.PropertyColumns) { if (jsonElement.TryGetProperty(column.ColumnName, out var value)) { var realValue = column.ColumnType.ConvertFromDatabase(value); column.PropertyInfo!.SetValue(result, realValue); } } return result; } public TEntity ConvertJsonToEntityForInsert(string json) { var jsonElement = JsonSerializer.Deserialize(json, _jsonSerializerOptions.CurrentValue); return ConvertJsonToEntityForInsert(jsonElement!); } public TEntity ConvertJsonToEntityForUpdate(JsonElement jsonElement, out UpdateBehavior updateBehavior) { if (jsonElement.ValueKind is not JsonValueKind.Object) throw new UserException("The jsonElement must be an object."); updateBehavior = UpdateBehavior.None; if (jsonElement.TryGetProperty("$saveNull", out var saveNullValue)) { if (saveNullValue.ValueKind is JsonValueKind.True) { updateBehavior |= UpdateBehavior.SaveNull; } else if (saveNullValue.ValueKind is JsonValueKind.False) { } else { throw new UserException("The $saveNull must be a boolean."); } } var result = Activator.CreateInstance(); foreach (var column in _table.PropertyColumns) { if (jsonElement.TryGetProperty(column.ColumnName, out var value)) { var realValue = column.ColumnType.ConvertFromDatabase(value); column.PropertyInfo!.SetValue(result, realValue); } } return result; } public TEntity ConvertJsonToEntityForUpdate(string json, out UpdateBehavior updateBehavior) { var jsonElement = JsonSerializer.Deserialize(json, _jsonSerializerOptions.CurrentValue); return ConvertJsonToEntityForUpdate(jsonElement!, out updateBehavior); } }