Skip to content

Commit 933748e

Browse files
committed
Improved serialization
1 parent 1d62ae3 commit 933748e

File tree

2 files changed

+78
-14
lines changed

2 files changed

+78
-14
lines changed

Magic.IndexedDb/IndexDbManager.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,6 @@ public MagicQuery<T> Where<T>(Expression<Func<T, bool>> predicate) where T : cla
374374

375375
// Preprocess the predicate to break down Any and All expressions
376376
var preprocessedPredicate = PreprocessPredicate(predicate);
377-
var asdf = preprocessedPredicate.ToString();
378377
CollectBinaryExpressions(preprocessedPredicate.Body, preprocessedPredicate, query.JsonQueries);
379378

380379
return query;

Magic.IndexedDb/Models/MagicContractResolver.cs

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Reflection;
44
using System.Text.Json.Serialization;
55
using System.Text.Json;
6+
using System.Collections;
67

78
namespace Magic.IndexedDb.Models
89
{
@@ -12,35 +13,99 @@ internal class MagicContractResolver<T> : JsonConverter<T>
1213

1314
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
1415
{
16+
// Defer deserialization back to built-in handling to ensure correctness
1517
return JsonSerializer.Deserialize<T>(ref reader, options);
1618
}
1719

1820
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
1921
{
20-
if (value == null) return;
21-
22-
writer.WriteStartObject();
22+
if (value == null)
23+
{
24+
writer.WriteNullValue();
25+
return;
26+
}
2327

24-
foreach (var property in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
28+
try
2529
{
26-
// Check cache first
27-
if (!_cachedIgnoredProperties.TryGetValue(property, out bool shouldIgnore))
30+
// Handle simple or primitive types directly
31+
if (IsSimpleType(typeof(T)))
2832
{
29-
shouldIgnore = property.GetCustomAttributes(inherit: true)
30-
.Any(a => a.GetType().FullName == typeof(MagicNotMappedAttribute).FullName);
31-
_cachedIgnoredProperties[property] = shouldIgnore;
33+
JsonSerializer.Serialize(writer, value, options);
34+
return;
3235
}
3336

34-
if (!shouldIgnore)
37+
// Handle collections
38+
if (value is IEnumerable enumerable && typeof(T) != typeof(string))
3539
{
36-
var propValue = property.GetValue(value);
40+
writer.WriteStartArray();
41+
foreach (var item in enumerable)
42+
{
43+
if (item == null)
44+
writer.WriteNullValue();
45+
else
46+
JsonSerializer.Serialize(writer, item, item.GetType(), options);
47+
}
48+
writer.WriteEndArray();
49+
return;
50+
}
51+
52+
// Handle complex objects
53+
writer.WriteStartObject();
54+
foreach (var property in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
55+
{
56+
if (ShouldIgnoreProperty(property))
57+
continue;
58+
3759
var propName = options.PropertyNamingPolicy?.ConvertName(property.Name) ?? property.Name;
60+
61+
if (property.GetIndexParameters().Length > 0)
62+
continue; // Skip indexers entirely
63+
64+
object? propValue;
65+
try
66+
{
67+
propValue = property.GetValue(value);
68+
}
69+
catch
70+
{
71+
// Fallback: write null if getting property fails
72+
propValue = null;
73+
}
74+
3875
writer.WritePropertyName(propName);
39-
JsonSerializer.Serialize(writer, propValue, property.PropertyType, options);
76+
if (propValue == null)
77+
writer.WriteNullValue();
78+
else
79+
JsonSerializer.Serialize(writer, propValue, propValue.GetType(), options);
4080
}
81+
writer.WriteEndObject();
82+
}
83+
catch
84+
{
85+
// Fallback to system serializer on complete failure
86+
JsonSerializer.Serialize(writer, value, value.GetType(), options);
4187
}
88+
}
4289

43-
writer.WriteEndObject();
90+
private static bool ShouldIgnoreProperty(PropertyInfo property)
91+
{
92+
return _cachedIgnoredProperties.GetOrAdd(property, prop =>
93+
prop.GetCustomAttributes(inherit: true)
94+
.Any(a => a.GetType().FullName == typeof(MagicNotMappedAttribute).FullName));
95+
}
96+
97+
private static bool IsSimpleType(Type type)
98+
{
99+
return type.IsPrimitive ||
100+
type.IsEnum ||
101+
type == typeof(string) ||
102+
type == typeof(decimal) ||
103+
type == typeof(DateTime) ||
104+
type == typeof(DateTimeOffset) ||
105+
type == typeof(Guid) ||
106+
type == typeof(Uri) ||
107+
type == typeof(TimeSpan);
44108
}
45109
}
110+
46111
}

0 commit comments

Comments
 (0)