Skip to content

Serializing with JSON #38

Open
Open
@msant7

Description

@msant7

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

Activity

davidjrh

davidjrh commented on Sep 10, 2020

@davidjrh
Owner

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

internal static byte[] SerializeXmlBinary(object obj)
that is not currently in use), etc. After lot of tests, the I got the best performance with binary uncompressed. Note that there is already an option to compress/decompress in place.

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

msant7 commented on Nov 23, 2020

@msant7
Author

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.SharedDictionary2.EnsureReadAccess() at DotNetNuke.Collections.Internal.SharedDictionary2.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:
image

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

Not sure if anyone has any ideas.... Thanks

mtrutledge

mtrutledge commented on Jan 5, 2022

@mtrutledge
Contributor

Was any progress on this ever made?

mtrutledge

mtrutledge commented on Feb 4, 2022

@mtrutledge
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Serializing with JSON · Issue #38 · davidjrh/dnn.rediscachingprovider