2

I am trying to add a complex object into Redis but while retrieving the values from Redis I am getting certain values as null. Below is the rough sample I am trying. I have an complex object, I serialize that complex object using JsonConvert and add it in the Redis. The property CollectionID has two counts with respective values but after getting it from Redis and De-serializing makes the value as null. Please check the below image

The property CollectionID has two values with ID:

enter image description here

The property becomes null while getting it from Redis cache So

Below is the sample:

class Program
{
    private static IDatabase _cache;
    private static ConnectionMultiplexer _connection;

    static void Main(string[] args)
    {
        _connection = ConnectionMultiplexer.Connect("localhost");
        _cache = _connection.GetDatabase();

        List<Id> id = new List<Id>() { new Id() { ID = 10 }, new Id() { ID = 20 } };
        Collection<Customers> collection = new Collection<Customers>() { new Customers(id) };
        Product product = new Product(new Guid(), collection, 1);
        _cache.StringSet("Redis_Key", GetSerializedString(product));
        var value = JsonConvert.DeserializeObject<Product>(_cache.StringGet("Redis_Key"));
    }

    private static String GetSerializedString<Test1>(Test1 value)
    {
        return JsonConvert.SerializeObject(
                    value,
                    Formatting.Indented,
                    new JsonSerializerSettings
                    {
                        ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
                        PreserveReferencesHandling = PreserveReferencesHandling.All
                    });
    }
}

public class Product
{
    public Product(
        Guid parentGuid,
        Collection<Customers> collection,
        int number)
    {
        _parentGuid = parentGuid;
        _collection = collection;
        _number = number;
    }

    private Guid _parentGuid;
    public Guid ParentGuid
    {
        get { return _parentGuid; }
    }

    private Collection<Customers> _collection;
    public Collection<Customers> Collection
    {
        get { return _collection; }
    }

    private int _number;
    public int number
    {
        get { return _number; }
    }
}

public class Customers
{
    public Customers(IEnumerable<Id> id)
    {
        _id = id;
    }

    private IEnumerable<Id> _id;

    public IEnumerable<Id> CollectionID
    {
        get { return _id; }
    }
}

public class Id
{
    public int ID { get; set; }
}

Any suggestions would be of much help.

Thanks, Anish

LeoMurillo
  • 6,048
  • 1
  • 19
  • 34
Anish
  • 219
  • 2
  • 12
  • Try refactoring to get and set the string separately from the serialization and deserialization. Comparing the raw strings should tell you whether it is a redis issue or a serialization issue – ste-fu Jan 31 '20 at 10:44

1 Answers1

3

The problem is you don't have a setter on CollectionID.

public IEnumerable<Id> CollectionID
{
    get { return _id; }
    set { _id = value; } //need a setter
}

If you need the setter to be private, you can do so but you will need a ContractResolver. You can add the package JsonNet.PrivateSettersContractResolvers, then add

using JsonNet.PrivateSettersContractResolvers;
...
var value = JsonConvert.DeserializeObject<Product>(_cache.StringGet("Redis_Key"),
        new JsonSerializerSettings
        {
            ContractResolver = new PrivateSetterContractResolver()
        });

See Private setters in Json.Net.

LeoMurillo
  • 6,048
  • 1
  • 19
  • 34
  • Hi Leo, your suggestion works but there is another scenario where the class 'Id' is inheriting an ISerializable class and it's returning the values as empty. Is there any way that JsonConvert serializes a class that is custom serialized already? – Anish Feb 07 '20 at 08:38
  • Sounds like a valid new question, please post it with more details as another question – LeoMurillo Feb 07 '20 at 11:32