Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialization issue in AliasService when using distributed cache #2056

Closed
hedronn opened this issue Apr 3, 2024 · 5 comments
Closed

Deserialization issue in AliasService when using distributed cache #2056

hedronn opened this issue Apr 3, 2024 · 5 comments
Assignees

Comments

@hedronn
Copy link

hedronn commented Apr 3, 2024

I am seeing the following exception raised when upgrading from v10.4 to v11.0

It appears to be an issue with Newtonsoft Deserialize of an enumerable of a specific type, I have tried clearing my cache and creating a new empty page object in Piranha CMS but still see the same issue (see details below). The project works using v10.4, but fails afer upgrade to v11.0 any thoughts?!?

[Exception]

Newtonsoft.Json.JsonSerializationException
HResult=0x80131500
Message=Cannot create and populate list type System.Linq.Enumerable+SelectListIterator`2[Piranha.Models.Alias,Piranha.Services.AliasService+AliasUrlCacheEntry]. Path '$values', line 1, position 172.
Source=Newtonsoft.Json
StackTrace:
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewList(JsonReader reader, JsonArrayContract contract, Boolean& createdFromNonDefaultCreator) in /_/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:line 1223

[Newtonsoft.Json.Serialization.JsonSerializerInternalReader]

// some types like non-generic IEnumerable can be serialized but not deserialized
if (!contract.CanDeserialize)
{
throw JsonSerializationException.Create(reader, "Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType));
}

[Type]

System.Linq.Enumerable+SelectListIterator`2[[Piranha.Models.Alias, Piranha, Version=11.0.0.0, Culture=neutral, PublicKeyToken=null],[Piranha.Services.AliasService+AliasUrlCacheEntry, Piranha, Version=11.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

@hedronn hedronn changed the title Issue upgrading existing v10.4 project to v11.0 Issue upgrading existing v10.4 project to v11.0 (Newtonsoft Deserialize exception) Apr 3, 2024
@tidyui
Copy link
Member

tidyui commented Apr 3, 2024

From the error message it appears the a list that is a result of a linq query (.Where(x => ...)) is being serialized directly without calling .ToList() before assigning the value. Is this error triggered internally from Piranha or is it from custom code in your project?

EDIT

By quickly looking at the AliasService we don't appear to be caching aliases in a collection but rather one by one, so I don't think we would be serializing a list of aliases internally.

@hedronn
Copy link
Author

hedronn commented Apr 3, 2024

Thanks for the prompt reply Håkan, I will investigate further and report back, but as I mentioned its the same project / custom code, working under v10.4 but not after upgrade to v11.0, that is what made me think this was as a result of a change to Piranha v11.0 updates.

@hedronn
Copy link
Author

hedronn commented Apr 3, 2024

From what I can tell looking at the Call Stack the exception is raised in Piranha.Core when the _cache.Get<IEnumerable> call in AliasService calls the DistributedCache class Get method fails due to the JsonConvert.DeserializeObject throwing an exception (see code below) when attempting to return the aliasUrls.

I don't think this is a cache issue as this code works in v10.4 of Piranha but fails in v11.0 for my project.

Piranha.Services.AliasService

/// <summary>
/// Gets the aliases for the specified site.
/// </summary>
private async Task<IEnumerable<AliasUrlCacheEntry>> GetAliasUrls(Guid siteId)
{
    if (_cache != null)
    {
        var aliasUrls = _cache.Get<IEnumerable<AliasUrlCacheEntry>>($"Piranha_AliasUrls_{siteId}");

        if (aliasUrls == null)
        {
            var aliases = await _repo.GetAll(siteId).ConfigureAwait(false);
            aliasUrls = aliases.Select(x => new AliasUrlCacheEntry
            {
                Id = x.Id,
                AliasUrl = x.AliasUrl
            });

            _cache.Set($"Piranha_AliasUrls_{siteId}", aliasUrls);
        }
        return aliasUrls;
    }
    return null;
}

Piranha.Cache.DistributedCache

/// <inheritdoc />
public T Get<T>(string key)
{
    var json = _cache.GetString(key);

    if (!string.IsNullOrEmpty(json))
    {
        return JsonConvert.DeserializeObject<T>(json, _jsonSettings);
    }
    return default(T);
}

@tidyui
Copy link
Member

tidyui commented Apr 3, 2024

From the stack I'm guessing the error is here:

aliasUrls = aliases.Select(x => new AliasUrlCacheEntry
{
   Id = x.Id,
   AliasUrl = x.AliasUrl
});

According to the exception changing it to the following would probably fix the error:

aliasUrls = aliases.Select(x => new AliasUrlCacheEntry
{
   Id = x.Id,
   AliasUrl = x.AliasUrl
}).ToList();

I'm assuming the error comes from an update in Newtonsoft since we updated to the latest version, but since we run integration tests with both memory and distributed cache I'll have to check why this error wasn't captured by the tests.

@hedronn
Copy link
Author

hedronn commented Apr 3, 2024

I'm assuming the error comes from an update in Newtonsoft since we updated to the latest version, but since we run integration tests with both memory and distributed cache I'll have to check why this error wasn't captured by the tests.

Thanks Håkan for taking the time to look into this issue, I look forward to the fix in v11.x

@hedronn hedronn closed this as completed Apr 3, 2024
@tidyui tidyui reopened this Apr 3, 2024
@tidyui tidyui self-assigned this Apr 3, 2024
@tidyui tidyui changed the title Issue upgrading existing v10.4 project to v11.0 (Newtonsoft Deserialize exception) Deserialization issue in AliasService when using distributed cache Apr 3, 2024
@tidyui tidyui closed this as completed in 3959378 Apr 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants