Azure / azure-functions-durable-extension

Durable Task Framework extension for Azure Functions
MIT License
717 stars 271 forks source link

Durable entity is created with null property values #2797

Open ccarmannt opened 7 months ago

ccarmannt commented 7 months ago

Description

When creating a durable entity, the entity is created with null values for the properties in the class.

This is how the entity looks in Azure Storage Explorer after a couple of runs:

[{},{}]

Expected behavior

Property values should be stored stored correctly.

Actual behavior

Property values are stored as nulls. When debugging, it appears that the Add operation in the durable entity class is receiving the object with null values: image

Relevant source code snippets

Function for creating the durable entity:

        [Function("CreateDurableEntity")]
        public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
            [DurableClient] DurableTaskClient client)
        {
            _logger.LogInformation("C# HTTP trigger function processed a request to create entities.");

            var entityId = new EntityInstanceId(nameof(MyDataTypeList), "myKey");
            var value1 = req.Query["value1"];
            var value2 = req.Query["value2"];
            var myData = new MyDataType { Value1 = value1, Value2 = value2 };
            await client.Entities.SignalEntityAsync(entityId, "Add", myData);

            return new OkObjectResult($"Queued creation of new entity with values {value1} and {value2}");
        }

datatype class:

namespace SimpleDurables;

public class MyDataType
{
    public string Value1;
    public string Value2;
}

Durable entity class:

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask.Entities;
using Microsoft.Extensions.Logging;

namespace SimpleDurables;

public class MyDataTypeList: TaskEntity<List<MyDataType>>
{
    readonly ILogger _logger;

    public MyDataTypeList(ILogger<MyDataTypeList> logger)
    {
        _logger = logger;
    }

    public void Add(MyDataType data) => State.Add(data);

    public void Remove(MyDataType data) => State.Remove(data);

    public void Reset() => State.Clear();

    public List<MyDataType> Get() => State;

    [Function(nameof(MyDataTypeList))]
    public Task RunEntityAsync([EntityTrigger] TaskEntityDispatcher dispatcher)
    {
        return dispatcher.DispatchAsync(this);
    }
}

Known workarounds

None found so far.

App Details

jaliyaudagedara commented 7 months ago

Your MyDataType, has fields and not properties. It should be something like below:

public class MyDataType
{
    public string Value1 { get; set; }
    public string Value2 { get; set; }
}
ccarmannt commented 7 months ago

@jaliyaudagedara Thank you for this. I was able to confirm this change indeed works.

However, I haven't been able to find anything in the documentation stating that this is required, or explaining why.

davidmrdavid commented 7 months ago

cc/ @sebastianburckhardt in case he can chime in