0

I have a class from a library, so I have no control on the class. Here is is:

public class EventLog<T> : IEventLog
    {
        public EventLog(T eventObject, FilterLog log)
        {
            Event = eventObject;
            Log = log;
        }

        public T Event { get; }
        public FilterLog Log { get; }
    }

I am getting a list of these. (a List<EventLog>) When I return this list from my activity function to the orchestrator, the T Event is null.

Having been playing about / googling the last few hours, I am no closer. I have a simplified test, where I have an orchestrator call an activity function and pass in a single EventLog<DepositEvent> as the input. Calling context.GetInput<EventLog<DepositEvent>>() on the activity function also results in the T Event being null.

In startup I have set the JsonSerializerSettings such that TypeNameHandling is TypeNameHandling.All. I have decorated the DepositEvent with [JsonObject] and [JsonProperty] on the parameters.

Whilst debugging, inspecting the non public members of context from the activity function I can see the serialised input. The serialised input has the typename as I would expect from the settings, and it has all the information. It is only when it is deserialised that it just makes the T Event null...

A sample of the beginning of the serialised JSON:

{
  "$type": "System.Object[], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
  "$values": [
    {
      "$type": "Nethereum.Contracts.EventLog`1[[xxx.xxx.Events.DepositEvent, xxx.xxx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Nethereum.Contracts, Version=4.5.0.0, Culture=neutral, PublicKeyToken=8768a594786aba4e",
      "Event": {
        "$type": "xxx.xxx.Events.DepositEvent, xxx.xxx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
        "From": "0x1234567890123456789012345678901234567890",
        "TokenId": 18082448916451024430800726619787705340592747687914198471720709142354080950600,
        "DomainLabel": "pingutest7"
      },
      "Log": {
        "$type": "Nethereum.RPC.Eth.DTOs.FilterLog, Nethereum.RPC, Version=4.5.0.0, Culture=neutral, PublicKeyToken=8768a594786aba4e",
        "removed": false,
........

So, I have absolutely everything required there to deserialise without issue I would think? I really cannot work out why the deserialisation doesn't work...

The DepositEvent class is:

[Event("Deposit")]
[Newtonsoft.Json.JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]
public class DepositEvent : IEventDTO
{
    [Parameter("address", "_from", 1, true)]
    [Newtonsoft.Json.JsonProperty("From")]
    public string From { get; set; } = null!;

    [Parameter("uint256", "_id", 2, true)]
    [Newtonsoft.Json.JsonProperty("TokenId")]
    public BigInteger TokenId { get; set; }

    [Parameter("string", "_domainLabel", 3, false)]
    [Newtonsoft.Json.JsonProperty("DomainLabel")]
    public string DomainLabel { get; set; } = null!;
}
pingu2k4
  • 956
  • 2
  • 15
  • 31
  • Your problem is that, for Json.NET to call the parameterized constructor with correctly deserialized arguments, the constructor argument names must match the JSON property names. But since `eventObject` and `Event` do not match, the `"Event"` property is not bound to the argument. See e.b. [Json.net `JsonConstructor` constructor parameter names](https://stackoverflow.com/a/43034838/3744182) or [JsonConstructor throws Exception even when the passed parameter is not null](https://stackoverflow.com/a/43034838/3744182). – dbc Jun 04 '22 at 05:07
  • You wrote, *I have no control on the class* so if you cannot fix the constructor argument name you will have to write a custom converter. However, it seems you are also serializing with `TypeNameHandling.All`. Do you need this also? Is your JSON format flexible even if `EventLog` cannot be changed? Because if you do need TypeNameHandling you will have to manually parse the `$type` property in the converter (or do something tricky with a custom contract resolver). – dbc Jun 04 '22 at 05:09
  • From the type information, you are also serializing a `System.Object[]` rather than a `List`. Do you need to do that? Is that why you are using TypeNameHandling? – dbc Jun 04 '22 at 05:12

0 Answers0