Прочный объект не десериализуется - PullRequest
2 голосов
/ 04 февраля 2020

Я пытаюсь использовать долговременную сущность в моей функции 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.

1 Ответ

1 голос
/ 11 февраля 2020

Мне удалось обойти это, следуя @ тихому предложению. Я перепроектировал класс сущности, чтобы использовать только типы CLR. В моем случае это означало замену Dictionary<string, ActionTargetIdsCacheItemInfo> двумя словарями Dictionary<string, List<string>> и Dictionary<string, DateTimeOffset>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...