3

I'm not sure how to explain our goal in words, so I'll hop straight to the code.

With our current json converter settings. We get the following result when converting one of our events.

{
    "PortfolioId": {
        "Id": "portId"
    },
    "EntityId": {
        "Id": "3cf7582b-3cad-4aeb-a671-0132ba97d60d"
    },
    "EventVersion": 1,
    "OccurredOn": "2018-08-08T09:52:03.7871323+02:00",
    "Id": "71fe3a2e-354a-4b19-abea-655471e96d72",
    "Creator": {
        "Id": "27a1d6b1-1ffa-4071-92ee-31c12bf120f0"
    },
    "CorrelationId": "3138dbe0-3a4d-4559-83e9-d1f3e5684ee8"
}

Our goal is to get a converted event that looks like this;

{
    "PortfolioId": "portId",
    "EntityId":  "3cf7582b-3cad-4aeb-a671-0132ba97d60d",
    "EventVersion": 1,
    "OccurredOn": "2018-08-08T09:52:03.7871323+02:00",
    "Id": "71fe3a2e-354a-4b19-abea-655471e96d72",
    "Creator": "27a1d6b1-1ffa-4071-92ee-31c12bf120f0",
    "CorrelationId": "3138dbe0-3a4d-4559-83e9-d1f3e5684ee8"
}

In the event we have an object of a certain type (i.e EntityId, PortfolioId) which holds the value in a property. All these Id types derive from an abstract class with the property "Id".

An event class looks like this.

 public class ExampleEvent : DomainEvent
{
    public PortfolioId PortfolioId { get; }
    public EntityId EntityId { get;}

    public ExampleEvent(
        PortfolioId portfolioId,
        EntityId entityId,
        UserId creator, Guid correlationId) : base(creator, correlationId)
    {
        PortfolioId = portfolioId;
        EntityId = entityId;
    }
}

ExampleEvent

Does anybody have an idea how one could do this. I thought this might be possible with a custom json converter but have no idea yet on how to implement this for this case.

EDIT: I should have stated that this has to be done one many event types. And that a generic reusable solution seems to fit best in order to keep the overhead low. This mean that it is probably best if the event class itself is not altered at all. (so preferably without attributes etc)

mrogal.ski
  • 5,828
  • 1
  • 21
  • 30
redlum
  • 89
  • 3
  • @TheGeneral Thank you for your reaction. I should have stated that we have many events. Due to this it is not really efficient to build a converter or a wrapper for every event. This would also cause more overhead when implementing new events. – redlum Aug 08 '18 at 09:04
  • AHh yeah i misunderstood what you were wanting, carry on – TheGeneral Aug 08 '18 at 09:05

3 Answers3

1

The second Approach in this answer could help in manipulating the serialization. Making a property deserialize but not serialize with json.net

M. Abouzeid
  • 167
  • 7
  • @Read Noor, Thank you for your reply. This might actually work. What do you think about the second answer where they use a ContractResolver. Do you think we would be able to connect this with the abstract class which they inherit from? – redlum Aug 08 '18 at 09:54
  • @redlum Yes, I think you can accomplish that using the ContractResolver. https://stackoverflow.com/questions/41088492/json-net-contractresolver-vs-jsonconverter In this answer use the *Change the contract used for a type* as a guide. – M. Abouzeid Aug 09 '18 at 02:49
0

You can use JsonIgnore attributes with calculated properties:

public class PortfolioId
{
    public string Id { get; set; }
}

public class EntityId
{
    public string Id { get; set; }
}

public class UserId
{
    public string Id { get; set; }
}

public class ExampleEvent 
{
    private ExampleEvent() // for JSON deserializer
    {
        Creator = new UserId();
        Portfolio = new PortfolioId();
        Entity = new EntityId();
    }

    // add your base constructor call
    public ExampleEvent(PortfolioId portfolio, EntityId entity, UserId creator)
    {
        Creator = creator;
        Portfolio = portfolio;
        Entity = entity;
    }

    [JsonIgnore]
    public UserId Creator { get; set; } 

    public string CreatorId
    {
        get => Creator.Id;
        set => Creator.Id = value;
    }

    [JsonIgnore]
    public PortfolioId Portfolio { get; set; } 

    public string PortfolioId
    {
        get => Portfolio.Id;
        set => Portfolio.Id = value;
    }

    [JsonIgnore]
    public EntityId Entity { get; set; } 

    public string EntityId
    {
        get => Entity.Id;
        set => Entity.Id = value;
    }

    public int EventVersion { get; set; }

    public string Id { get; set; }

    public string CorrelationId { get; set; }
}
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
0

Incase JsonIgnore does not suites your need or you need more customization you may also look for IContractResolver with JsonProperty.ShouldDeserialize / JsonProperty.ShouldSerialize. here some examples.

Rajib Dey
  • 54
  • 4