Open
Description
Hi, I was wondering if anyone had any thoughts about serializing with JSON instead of BinaryFormatter. I implemented the following as a test on my local dev and it seems to work well:
https://patrickdesjardins.com/blog/serializing-complex-object-for-redis
PROS
- The big PRO is that you don't have to add and maintain [Serializable] to all your classes being cached in Redis.
CONS - Small size increase, could compress but obviously adds overhead
- It won't honor [NonSerialized] attributes, but I guess it would honor [JsonIgnore] attributes
- It could be potentially easier for someone to inject a "Bad" object in the cache since the type is included in the cached object.
Here is an example of a cached item...
get dma9_DNN_SkinDefaults_SkinInfo
"{\r\n "$id": "1",\r\n "$type": "DotNetNuke.UI.Skins.SkinDefaults, DotNetNuke",\r\n "AdminDefaultName": "Admin.ascx",\r\n "DefaultName": "Inner.ascx",\r\n "Folder": "/Xcillion/"\r\n}"
Just curious if anyone has any thoughts on this or have tried this with DNN. Thanks
Metadata
Metadata
Assignees
Labels
No labels
Activity
davidjrh commentedon Sep 10, 2020
Sounds really interesting to me. When I built this module some time back, I tried with different serializers like DataContract, XmlSerializer (there is still code about it
dnn.rediscachingprovider/RedisCachingProvider/Shared.cs
Line 66 in c938a92
At that time, I didn't try with any JSON serialization, and after reviewing this post (https://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/), I'm thinking that having the option to use JSON or even other serializers would be an interesting experiment. Seems that just with JSON the performance would be better than binary.
Do you have measured the performance with lot of objects (small and large) so we can do some type of comparison?
On the other hand, the binary serializer can even serialize/deserialize private properties, not sure if that's possible with the other ones.
msant7 commentedon Nov 23, 2020
Just to give an update on this. Everything was looking good, I was getting really good results on size and time, but then I hit a roadblock. I get the following exception:
Exception of type 'DotNetNuke.Collections.Internal.ReadLockRequiredException' was thrown.
at DotNetNuke.Collections.Internal.SharedDictionary
2.EnsureReadAccess() at DotNetNuke.Collections.Internal.SharedDictionary
2.IEnumerable_GetEnumerator()at Newtonsoft.Json.Utilities.DictionaryWrapper`2.System.Collections.IDictionary.GetEnumerator()
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Formatting formatting, JsonSerializerSettings settings)
at DotNetNuke.Providers.RedisCachingProvider.Shared.SerializeJSON(Object source) in C:\dnnsites\ot9\Providers\CachingProviders\RedisCachingProvider\RedisCachingProvider\Shared.cs:line 110
at DotNetNuke.Providers.RedisCachingProvider.RedisCachingProvider.Insert(String key, Object value, DNNCacheDependency dependency, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback) in C:\dnnsites\ot9\Providers\CachingProviders\RedisCachingProvider\RedisCachingProvider\RedisCachingProvider.cs:line 205
This occurs when TabInfo is serialized. What is specifically causing it is the following member variables:

In order for those elements to be accessed, it needs to be accessed as follows, or you can't read the element.

Not sure if anyone has any ideas.... Thanks
mtrutledge commentedon Jan 5, 2022
Was any progress on this ever made?
mtrutledge commentedon Feb 4, 2022
I am going to take a slightly different approach here. If the JSON serialization fails for some reason I am going to fall back to Binary serialization. Then check for base64encoded strings during deserialization.