持久实体不会反序列化

问题描述 投票:1回答:1

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

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

[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

json.net azure-functions azure-durable-functions
1个回答
0
投票

我确实设法通过遵循@silent建议来解决此问题。我将实体类重新设计为仅使用CLR类型。就我而言,这意味着用两个字典Dictionary<string, ActionTargetIdsCacheItemInfo>Dictionary<string, List<string>>替换Dictionary<string, DateTimeOffset>

© www.soinside.com 2019 - 2024. All rights reserved.