I'm doing a basic serialize / deserialize with $type included to implement the outbox pattern. however I'm getting the default values.
Here's the code serializing :
JsonConvert.SerializeObject(domainEvent,
new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }
and for de-serializing
var domainEvent = JsonConvert.DeserializeObject<IDomainEvent>(
serializedDomainEvent,
new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All});
here's the domain event i'm trying to serialize
public record SubscriptionSet(Subscription subscription) : IDomainEvent
and lastly the subscription class
public class Subscription : AggregateRoot
{
private readonly List<Alert> _alerts = new();
public Guid UserId { get; private set; }
public SubscriptionTier subscriptionTier { get; private set; }
public SubscriptionPlan subscriptionPlan { get; private set; }
public DateOnly StartDate { get; private set; }
public DateOnly EndDate { get; private set; }
public bool IsVaild { get; private set; }
public decimal ComulativeTradingVolume24H { get; private set; }
public IReadOnlyList<Alert> Alerts => _alerts.ToList();
}
The serialization part is working properly but i'm messing up the deserialization part.
This is the serialization output :
{"$type":"Domain.Subscriptions.Events.SubscriptionSet, Domain","subscription":{"$type":"Domain.Subscriptions.Subscription, Domain","UserId":"e09cf0c7-5cc7-4fd7-b899-ac9dc74a70a4","subscriptionTier":1,"subscriptionPlan":1,"StartDate":"2024-12-05","EndDate":"2025-03-05","IsVaild":true,"ComulativeTradingVolume24H":0.0,"Alerts":{"$type":"System.Collections.Generic.List`1[[Domain.Users.Alert, Domain]], System.Private.CoreLib","$values":[]},"Id":"ad35aeb0-c2dc-4ac2-a19f-e7fe9fcbc0c9"}}
As Told by the awesome people in the Comments, Private setters was the problem
public Guid UserId { get; private set; }
in order for this to work, either change setter to public or user [JsonProperty]
[JsonProperty]
public Guid UserId { get; private set; }
or if you don't like to decorate your classes with attributes you can, implement a custom contract resolver
public class PrivateResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member,
MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
if (!prop.Writable)
{
var property = member as PropertyInfo;
bool hasPrivateSetters = property?.GetSetMethod(true) != null;
prop.Writable = hasPrivateSetters;
}
return prop;
}
}
and in your de-serialization code do this
var domainEvent = JsonConvert.DeserializeObject<IDomainEvent>(
outboxMessage.Content,
new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.All ,
ContractResolver = new PrivateResolver() });