.Net Activity not returning Result

In .Net when i try to get the “response” from activity, the returned object it’s always like a new instance and not the instance that i used on return.
For example, i’m returning the below result
And at workflow the response is like a new instance of Result without any property filled.
What do i have to do to get the returned object?
P.S - i already tried with another kind of class

Workflow and activity results are serialized and put in history and returned to the caller deserliazed from the server, not directly. Activities may not even execute on the same machine as the workflow that called them.

Ok, nice!
So it’s a problem with serialization? Because the returned value is different or in this case like a default instance.

I’d have to see your code to know the problem, but by default the SDK tries to serialize/deserialize to/from JSON. See the conversion section of the README.

I see, let me give more details.

Here’s how i’m initializing the client and the worker.

Here’s what i’m returning from the activity.

        if (importZone.Items.Any(x => !string.IsNullOrEmpty(x.Errors)))
            await _mediator.Publish(new ImportFailedEvent(importZone));

            _logger.LogError("Carrier validation failed");
            return Result.Fail("Carrier validation failed");

        return Result.Ok();

And at workflow level, this values are not being correctly serialized. It’s returning like a default instance.

I need to see the signature of the activity and the invocation of the activity from the workflow and the class of the return type. The workflow deserializes using JSON based on result type of the lambda expression of the activity (or you have to set the result type explicitly when you ask for result if you are not using typesafe lambda expressions). By default, if it doesn’t work with System.Text.Json it won’t work as a return type.

This is the method/activity
Do i need to pass any parameter on the Attribute?

This does not show calling from workflow or what Result is. Can Result.Ok be properly serialized/deserialized to/from System.Text.Json with the Result type to the .NET JSON deserialize call?

For example, what does var jsonString = JsonSerializer.Serialize(Result.Ok()) return? And if you give that to var obj = JsonSerializer.Deserialize<Result>(jsonString) what is in obj? This is how .NET JSON serialization works, but I fear you have a sum type which is not compatible with .NET JSON serialization.

Got it, i expected the serialization for this class works because it’s the same class which we are using in another project with Hangfire. I’ll try to do these tests.

I am not familiar with Hangfire, but a quick glance shows they do a combination of JSON serialization as well as adding extra information for which type name it is. This is inherently .NET specific and Temporal uses JSON without such metadata so it can work across languages (think of it like an HTTP API). But if you want to take this approach, the conversion is customizable. It is advanced, but you can override the payload converter of the data converter to include the .NET assembly type name in the payload metadata on conversion to payload, and use that metadata to create a certain type on conversion from payload.

sure, i see now it’s a different paradigm. I don’t want to waste time creating custom serializers, it’s not worth the work, i’ll try a different approach maybe create a simple class.
Thanks a lot for the explanation.

Happy to help! Yes it’s very common for Temporal users to create models (e.g. simple records) specific for Temporal use and translate from other models. This makes them easy to adjust without affecting other parts of the system. Yes, often sum types and other abstract data types do not work well with multi-language serialization mechanisms like pure JSON.

1 Like