持久实体不会反序列化

A durable entity does not deserialize

我正在尝试在我的 Azure 函数中使用持久实体来缓存一些数据。但是,当我第一次尝试检索实体(状态)时,我收到一个异常,指示在实体反序列化期间出现问题。

这是我的实体class和相关代码

[JsonObject(MemberSerialization.OptIn)]
public class ActionTargetIdCache : IActionTargetIdCache
{

    [JsonProperty("cache")]
    public Dictionary<string, ActionTargetIdsCacheItemInfo> Cache { get; set; } = new Dictionary<string, ActionTargetIdsCacheItemInfo>();

    public void CacheCleanup(DateTime currentUtcTime)
    {
        foreach (string officeHolderId in Cache.Keys)
        {
            TimeSpan cacheItemAge = currentUtcTime - Cache[officeHolderId].lastUpdatedTimeStamp;

            if (cacheItemAge > TimeSpan.FromMinutes(2))
            {
                Cache.Remove(officeHolderId);
            }
        }
    }

    public void DeleteActionTargetIds(string officeHolderId)
    {
        if (this.Cache.ContainsKey(officeHolderId))
        {
            this.Cache.Remove(officeHolderId);
        }
    }

    public void DeleteState()
    {
        Entity.Current.DeleteState();
    }


    public void SetActionTargetIds(ActionTargetIdsCacheEntry entry)
    {
        this.Cache[entry.Key] = entry.Value;
    }

    public Task<ActionTargetIdsCacheItemInfo> GetActionTargetIdsAsync(string officeHolderId)
    {
        if (this.Cache.ContainsKey(officeHolderId))
        {
            return Task.FromResult(Cache[officeHolderId]);
        }
        else
        {
            return Task.FromResult(new ActionTargetIdsCacheItemInfo());
        }
    }
    // public void Reset() => this.CurrentValue = 0;
    // public int Get() => this.CurrentValue;

    [FunctionName(nameof(ActionTargetIdCache))]
    public static Task Run([EntityTrigger]  IDurableEntityContext ctx)
      => ctx.DispatchAsync<ActionTargetIdCache>();
}

public class ActionTargetIdsCacheEntry
{
    // officeHolderId
    public string Key { get; set; } = string.Empty;
    public ActionTargetIdsCacheItemInfo Value { get; set; } = new ActionTargetIdsCacheItemInfo();
}

[JsonObject(MemberSerialization.OptIn)]
public class ActionTargetIdsCacheItemInfo : ISerializable
{
    public ActionTargetIdsCacheItemInfo()
    {
        lastUpdatedTimeStamp = DateTime.UtcNow;
        actionTargetIds = new List<string>();
    }

    public ActionTargetIdsCacheItemInfo(SerializationInfo info, StreamingContext context)
    {
        lastUpdatedTimeStamp = info.GetDateTime("lastUpdated");
        actionTargetIds = (List<string>)info.GetValue("actionTargetIds", typeof(List<string>));
    }

    [JsonProperty]
    public DateTimeOffset lastUpdatedTimeStamp { get; set; } = DateTimeOffset.UtcNow;
    [JsonProperty]
    public List<string> actionTargetIds { get; set; } = new List<string>();

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("lastUpdated", lastUpdatedTimeStamp);
        info.AddValue("actionTargetIds", actionTargetIds);
    }
}

    public interface IActionTargetIdCache
{
    void CacheCleanup(DateTime currentUtcTime);
    void DeleteActionTargetIds(string officeHolderId);

    void DeleteState();
    void SetActionTargetIds(ActionTargetIdsCacheEntry item);
    // Task Reset();
    Task<ActionTargetIdsCacheItemInfo> GetActionTargetIdsAsync(string officeHolderId);
    // void Delete();
}

这是我第一次尝试使用 GetActionTargetIdsAsync 方法从编排访问状态时遇到的异常:



Exception has occurred: CLR/Microsoft.Azure.WebJobs.Extensions.DurableTask.EntitySchedulerException
Exception thrown: 'Microsoft.Azure.WebJobs.Extensions.DurableTask.EntitySchedulerException' in System.Private.CoreLib.dll: 'Failed to populate entity state from JSON: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'PolTrack.CdbGetFunctionApp.ActionTargetIdsCacheItemInfo' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'cache.officeHolderId1', line 1, position 29.'
 Inner exceptions found, see $exception in variables window for more details.
 Innermost exception     Newtonsoft.Json.JsonSerializationException : Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'PolTrack.CdbGetFunctionApp.ActionTargetIdsCacheItemInfo' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'cache.officeHolderId1', line 1, position 29.

有足够 SO 权限的人可以添加标签 azure-durable-entities

我确实按照@silent 的建议设法解决了这个问题。我将实体 class 重新设计为仅使用 CLR 类型。在我的例子中,这意味着用两个字典 Dictionary<string, List<string>>Dictionary<string, DateTimeOffset>.

替换 Dictionary<string, ActionTargetIdsCacheItemInfo>