I'm using Azure Durable Functions and have an activity that returns a list of objects of my custom class.When I check the result in the Activity Function before it's returned, everything seems correct.
However, in the orchestrator, I only get an initialized list with the correct number of elements, but the objects themselves are empty—none of their properties have values.
Has anyone encountered this issue before, or does anyone know why the objects might be getting "zeroed out" when passed from the activity to the orchestrator?
My Code:
Orchestrator
public static class OrchestratorFunc
{
[Function(nameof(OrchestratorFunc))]
public static async Task RunOrchestrator([OrchestrationTrigger] TaskOrchestrationContext context)
{
ILogger logger = context.CreateReplaySafeLogger(nameof(OrchestratorFunc));
using (logger.BeginScope(new Dictionary<string, object> { ["OrchestrationInstanceId"] = context.InstanceId }))
{
logger.LogInformation($"OrchestratorFunc Executed. InstanceId={context.InstanceId}");
var accessToken = await context.CallActivityAsync<string>(nameof(RetrieveAccessTokenActivity));
var companies = await context.CallActivityAsync<IEnumerable<CompanyModel>>(nameof(GetCompaniesActivity), accessToken);
logger.LogInformation($"OrchestratorFunc completed");
}
}
}
Activity Function (GetCompaniesActivity)
internal class GetCompaniesActivity
{
private readonly HttpClient _httpClient;
public GetCompaniesActivity(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient();
}
[Function(nameof(GetCompaniesActivity))]
public async Task<IEnumerable<CompanyModel>> Run([ActivityTrigger] string accessToken, string instanceId, FunctionContext executionContext)
{
ILogger logger = executionContext.GetLogger(nameof(GetCompaniesActivity));
var result = new List<CompanyModel>();
using (logger.BeginScope(new Dictionary<string, object> { ["OrchestrationInstanceId"] = instanceId }))
{
using var request = new HttpRequestMessage(HttpMethod.Get, "http://");
request.Headers.Add("Authorization", $"Bearer Authorization: {accessToken}");
var response = await _httpClient.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var jsonResponse = await response.Content.ReadAsStringAsync();
var companiesResponse = JsonConvert.DeserializeObject<CompanyResponse>(jsonResponse);
if (companiesResponse != null && companiesResponse.Companies != null)
{
result.AddRange(companiesResponse.Companies);
}
}
else
{
throw new TaskFailedException($"{response.StatusCode} {response.ReasonPhrase}");
}
return result.AsEnumerable<CompanyModel>();
}
}
}
CompanyModel:
[JsonObject(MemberSerialization.OptIn)]
public class CompanyResponse
{
[JsonProperty("results")]
public required List<CompanyModel> Companies;
}
[JsonObject(MemberSerialization.OptIn)]
public class CompanyModel
{
[JsonProperty("id")]
public Guid Id;
[JsonProperty("companyName")]
public required string CompanyName;
[JsonProperty("street")]
public required string Street;
[JsonProperty("zip")]
public required string Zip;
[JsonProperty("city")]
public required string City;
[JsonProperty("country")]
public required string Country;
[JsonProperty("vat")]
public required string VAT;
[JsonProperty("sys")]
public int? Sys;
[JsonProperty("idExternal")]
public required string IdExternal;
public override string ToString()
{
return $"{CompanyName} - {Id} - {IdExternal}";
}
}
The return value from my Activity Function:
The returned list in Orchestrator
I tried both IEnumerable and List—no difference. I also experimented with the JSON properties, but without success. The custom CompanyModel is correctly deserialized in the activity function, but in the orchestrator, all values are missing, even though the object is initialized.