Serializer Issues with EfCoreSecondLevelCacheInterceptor
Description
I've been attempting to use EasyCaching.Redis as the cache provider for the EFCoreSecondLevelCacheInterceptor, but I haven't found a Serializer that's working. I've tried all three options:
- EasyCaching.Serialization.Json
- EasyCaching.Serialization.MessagePack
- EasyCaching.Serialization.SystemTextJson
Both Serilization.Json and Serialization.SystemTextJson give the error:
Unable to translate bytes [84] at index 0 from specified code page to Unicode.
Serialization.MessagePack gives:
MessagePackSerializationException: Unexpected msgpack code 123 (positive fixint) encountered.
Related code
Here is the code that's being used to add the libraries to the middleware.
builder.Services.AddEFSecondLevelCache(options =>
{
options.UseEasyCachingCoreProvider(providerName, CacheExpirationMode.Sliding,
TimeSpan.FromMinutes(builder.Configuration.GetValue<double>("EFCoreSecondLevelCacheInterceptor:EntityCacheDuration")))
.DisableLogging(!builder.Environment.IsDevelopment()).UseCacheKeyPrefix("EF_");
});
builder.Services.AddEasyCaching(option =>
{
option.UseRedis(builder.Configuration, providerName, "EasyCaching:Redis");
option.WithJson(providerName);
});
The EasyCache settings:
"EasyCaching": {
"Redis": {
"MaxRdSecond": 120, //The max random second. If this value greater then zero, the seted cache items' expiration will add a random second. This is mainly for preventing Cache Crash
"EnableLogging": true,
"LockMs": 5000, //Mutex key's alive time(ms), default is 5000
"SleepMs": 300, //When mutex key alive, it will sleep some time, default is 300
"DbConfig": {
"Password": *******,
"ConnectionTimeout": 5000,
"AllowAdmin": true,
"Endpoints": [
{
"Host": ********,
"Port": 6380
}
],
"Database": 0, //The Redis database index the cache will use
"AsyncTimeout": 5000, //Specifies the time in milliseconds that the system should allow for asynchronous operations (defaults to SyncTimeout)
"SyncTimeout": 5000, //Specifies the time in milliseconds that the system should allow for synchronous operations (defaults to 5 seconds)
"SerializerName": "Redis"
}
}
},
The EF query that's being called is
int? restaurantId = (from c in _unitOfWork.LmsContext.Corporations
join r in _unitOfWork.LmsContext.Restaurants
on c.CorpID equals r.CorpID
where c.CorpCode == corporationCode && r.RestaurantNumber == restNum
select r.RestaurantID).Cacheable().FirstOrDefault();
The resulting exception stacktrace when using EasyCaching.Serialization.Json is
[19:17:20 ERR] An exception occurred while iterating over the results of a query for context type 'LaborManagement.Data.LmsContext'.
System.Text.DecoderFallbackException: Unable to translate bytes [84] at index 0 from specified code page to Unicode.
at System.Text.DecoderExceptionFallbackBuffer.Throw(Byte[] bytesUnknown, Int32 index)
at System.Text.DecoderExceptionFallbackBuffer.Fallback(Byte[] bytesUnknown, Int32 index)
at System.Text.Encoding.GetCharsWithFallback(ReadOnlySpan`1 bytes, Int32 originalBytesLength, Span`1 chars, Int32 originalCharsLength, DecoderNLS decoder)
at System.Text.UTF8Encoding.GetCharsWithFallback(ReadOnlySpan`1 bytes, Int32 originalBytesLength, Span`1 chars, Int32 originalCharsLength, DecoderNLS decoder)
at System.Text.Encoding.GetCharsWithFallback(Byte* pOriginalBytes, Int32 originalByteCount, Char* pOriginalChars, Int32 originalCharCount, Int32 bytesConsumedSoFar, Int32 charsWrittenSoFar, DecoderNLS decoder)
at System.Text.Encoding.GetChars(Byte* pBytes, Int32 byteCount, Char* pChars, Int32 charCount, DecoderNLS decoder)
at System.Text.DecoderNLS.GetChars(Byte* bytes, Int32 byteCount, Char* chars, Int32 charCount, Boolean flush)
at System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteCount, Char[] chars, Int32 charIndex, Boolean flush)
at System.IO.StreamReader.ReadBuffer(Span`1 userBuffer, Boolean& readToUserBuffer)
at System.IO.StreamReader.ReadSpan(Span`1 buffer)
at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
at EasyCaching.Serialization.Json.DefaultJsonSerializer.Deserialize[T](Byte[] bytes)
at EasyCaching.Redis.DefaultRedisCachingProvider.BaseGet[T](String cacheKey)
at EasyCaching.Core.EasyCachingAbstractProvider.Get[T](String cacheKey)
at EFCoreSecondLevelCacheInterceptor.EFEasyCachingCoreProvider.<>c__DisplayClass7_0.<GetValue>b__0() in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\EFEasyCachingCoreProvider.cs:line 113
at EFCoreSecondLevelCacheInterceptor.ReaderWriterLockProvider.TryReadLocked[T](Func`1 action, Int32 timeout) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\ReaderWriterLockProvider.cs:line 56
at EFCoreSecondLevelCacheInterceptor.DbCommandInterceptorProcessor.ProcessExecutingCommands[T](DbCommand command, DbContext context, T result) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\DbCommandInterceptorProcessor.cs:line 164
at EFCoreSecondLevelCacheInterceptor.SecondLevelCacheInterceptor.ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult`1 result) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\SecondLevelCacheInterceptor.cs:line 206
at Microsoft.EntityFrameworkCore.Diagnostics.Internal.RelationalCommandDiagnosticsLogger.CommandReaderExecuting(IRelationalConnection connection, DbCommand command, DbContext context, Guid commandId, Guid connectionId, DateTimeOffset startTime, CommandSource commandSource)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
System.Text.DecoderFallbackException: Unable to translate bytes [84] at index 0 from specified code page to Unicode.
at System.Text.DecoderExceptionFallbackBuffer.Throw(Byte[] bytesUnknown, Int32 index)
at System.Text.DecoderExceptionFallbackBuffer.Fallback(Byte[] bytesUnknown, Int32 index)
at System.Text.Encoding.GetCharsWithFallback(ReadOnlySpan`1 bytes, Int32 originalBytesLength, Span`1 chars, Int32 originalCharsLength, DecoderNLS decoder)
at System.Text.UTF8Encoding.GetCharsWithFallback(ReadOnlySpan`1 bytes, Int32 originalBytesLength, Span`1 chars, Int32 originalCharsLength, DecoderNLS decoder)
at System.Text.Encoding.GetCharsWithFallback(Byte* pOriginalBytes, Int32 originalByteCount, Char* pOriginalChars, Int32 originalCharCount, Int32 bytesConsumedSoFar, Int32 charsWrittenSoFar, DecoderNLS decoder)
at System.Text.Encoding.GetChars(Byte* pBytes, Int32 byteCount, Char* pChars, Int32 charCount, DecoderNLS decoder)
at System.Text.DecoderNLS.GetChars(Byte* bytes, Int32 byteCount, Char* chars, Int32 charCount, Boolean flush)
at System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteCount, Char[] chars, Int32 charIndex, Boolean flush)
at System.IO.StreamReader.ReadBuffer(Span`1 userBuffer, Boolean& readToUserBuffer)
at System.IO.StreamReader.ReadSpan(Span`1 buffer)
at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
at EasyCaching.Serialization.Json.DefaultJsonSerializer.Deserialize[T](Byte[] bytes)
at EasyCaching.Redis.DefaultRedisCachingProvider.BaseGet[T](String cacheKey)
at EasyCaching.Core.EasyCachingAbstractProvider.Get[T](String cacheKey)
at EFCoreSecondLevelCacheInterceptor.EFEasyCachingCoreProvider.<>c__DisplayClass7_0.<GetValue>b__0() in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\EFEasyCachingCoreProvider.cs:line 113
at EFCoreSecondLevelCacheInterceptor.ReaderWriterLockProvider.TryReadLocked[T](Func`1 action, Int32 timeout) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\ReaderWriterLockProvider.cs:line 56
at EFCoreSecondLevelCacheInterceptor.DbCommandInterceptorProcessor.ProcessExecutingCommands[T](DbCommand command, DbContext context, T result) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\DbCommandInterceptorProcessor.cs:line 164
at EFCoreSecondLevelCacheInterceptor.SecondLevelCacheInterceptor.ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult`1 result) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\SecondLevelCacheInterceptor.cs:line 206
at Microsoft.EntityFrameworkCore.Diagnostics.Internal.RelationalCommandDiagnosticsLogger.CommandReaderExecuting(IRelationalConnection connection, DbCommand command, DbContext context, Guid commandId, Guid connectionId, DateTimeOffset startTime, CommandSource commandSource)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
The stacktrace for the exception when using Serialization.MessagePack is:
[19:29:51 ERR] An exception occurred while iterating over the results of a query for context type 'LaborManagement.Data.LmsContext'.
MessagePack.MessagePackSerializationException: Failed to deserialize EFCoreSecondLevelCacheInterceptor.EFCachedData value.
---> MessagePack.MessagePackSerializationException: Unexpected msgpack code 123 (positive fixint) encountered.
at MessagePack.MessagePackReader.ThrowInvalidCode(Byte code)
at MessagePack.MessagePackReader.TryReadMapHeader(Int32& count)
at MessagePack.MessagePackReader.ReadMapHeader()
at MessagePack.Formatters.EFCoreSecondLevelCacheInterceptor_EFCachedDataFormatter1.Deserialize(MessagePackReader& reader, MessagePackSerializerOptions options)
at MessagePack.MessagePackSerializer.Deserialize[T](MessagePackReader& reader, MessagePackSerializerOptions options)
--- End of inner exception stack trace ---
at MessagePack.MessagePackSerializer.Deserialize[T](MessagePackReader& reader, MessagePackSerializerOptions options)
at MessagePack.MessagePackSerializer.Deserialize[T](ReadOnlyMemory`1 buffer, MessagePackSerializerOptions options, CancellationToken cancellationToken)
at EasyCaching.Serialization.MessagePack.DefaultMessagePackSerializer.Deserialize[T](Byte[] bytes)
at EasyCaching.Redis.DefaultRedisCachingProvider.BaseGet[T](String cacheKey)
at EasyCaching.Core.EasyCachingAbstractProvider.Get[T](String cacheKey)
at EFCoreSecondLevelCacheInterceptor.EFEasyCachingCoreProvider.<>c__DisplayClass7_0.<GetValue>b__0() in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\EFEasyCachingCoreProvider.cs:line 113
at EFCoreSecondLevelCacheInterceptor.ReaderWriterLockProvider.TryReadLocked[T](Func`1 action, Int32 timeout) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\ReaderWriterLockProvider.cs:line 56
at EFCoreSecondLevelCacheInterceptor.DbCommandInterceptorProcessor.ProcessExecutingCommands[T](DbCommand command, DbContext context, T result) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\DbCommandInterceptorProcessor.cs:line 164
at EFCoreSecondLevelCacheInterceptor.SecondLevelCacheInterceptor.ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult`1 result) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\SecondLevelCacheInterceptor.cs:line 206
at Microsoft.EntityFrameworkCore.Diagnostics.Internal.RelationalCommandDiagnosticsLogger.CommandReaderExecuting(IRelationalConnection connection, DbCommand command, DbContext context, Guid commandId, Guid connectionId, DateTimeOffset startTime, CommandSource commandSource)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
MessagePack.MessagePackSerializationException: Failed to deserialize EFCoreSecondLevelCacheInterceptor.EFCachedData value.
---> MessagePack.MessagePackSerializationException: Unexpected msgpack code 123 (positive fixint) encountered.
at MessagePack.MessagePackReader.ThrowInvalidCode(Byte code)
at MessagePack.MessagePackReader.TryReadMapHeader(Int32& count)
at MessagePack.MessagePackReader.ReadMapHeader()
at MessagePack.Formatters.EFCoreSecondLevelCacheInterceptor_EFCachedDataFormatter1.Deserialize(MessagePackReader& reader, MessagePackSerializerOptions options)
at MessagePack.MessagePackSerializer.Deserialize[T](MessagePackReader& reader, MessagePackSerializerOptions options)
--- End of inner exception stack trace ---
at MessagePack.MessagePackSerializer.Deserialize[T](MessagePackReader& reader, MessagePackSerializerOptions options)
at MessagePack.MessagePackSerializer.Deserialize[T](ReadOnlyMemory`1 buffer, MessagePackSerializerOptions options, CancellationToken cancellationToken)
at EasyCaching.Serialization.MessagePack.DefaultMessagePackSerializer.Deserialize[T](Byte[] bytes)
at EasyCaching.Redis.DefaultRedisCachingProvider.BaseGet[T](String cacheKey)
at EasyCaching.Core.EasyCachingAbstractProvider.Get[T](String cacheKey)
at EFCoreSecondLevelCacheInterceptor.EFEasyCachingCoreProvider.<>c__DisplayClass7_0.<GetValue>b__0() in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\EFEasyCachingCoreProvider.cs:line 113
at EFCoreSecondLevelCacheInterceptor.ReaderWriterLockProvider.TryReadLocked[T](Func`1 action, Int32 timeout) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\ReaderWriterLockProvider.cs:line 56
at EFCoreSecondLevelCacheInterceptor.DbCommandInterceptorProcessor.ProcessExecutingCommands[T](DbCommand command, DbContext context, T result) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\DbCommandInterceptorProcessor.cs:line 164
at EFCoreSecondLevelCacheInterceptor.SecondLevelCacheInterceptor.ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult`1 result) in F:\Prog\1398\EFCoreSecondLevelCacheInterceptor\src\EFCoreSecondLevelCacheInterceptor\SecondLevelCacheInterceptor.cs:line 206
at Microsoft.EntityFrameworkCore.Diagnostics.Internal.RelationalCommandDiagnosticsLogger.CommandReaderExecuting(IRelationalConnection connection, DbCommand command, DbContext context, Guid commandId, Guid connectionId, DateTimeOffset startTime, CommandSource commandSource)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
Specifications
- Provider : EasyCaching.Redis(version 1.6.1)
- Interceptor : EFCoreSecondLevelCacheInterceptor(version 3.6.3)
- Serializer : EasyCaching.Serialization.Json(version 1.6.1)
@gary-roach Thanks for your interest in this project.
It seems that there are some encoding issues.
Could you please check and provide some test data for us to reproduce it?
No response, Closed!