skip to Main Content

I’m using ServiceStack Redis. I have an struct and I want to storage it in Redis. But when I try to get it, it always return the default value. But if I change the struct for class it works ok. Any ideas?

public struct PersonStruct
{
    public string Name { get; set; }
    public int Year { get; set; }
}

Unit test (It always pass, because redis return the default for the struct)

var obj = new PersonStruct() {Name = "SomeName", Year = 1235};
_redis.Set(key, obj, TimeSpan.FromMinutes(2));
var result = _redis.Get<PersonStruct>(key);

Assert.AreEqual(default(PersonStruct), result);

2

Answers


  1. For structs you have to use custom serializer/deserializer

    var obj = new PersonStruct() {Name = "SomeName", Year = 1235};
    var bytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(obj));
    
    _redis.Set(key, bytes, TimeSpan.FromMinutes(2));
    
    var getBytes = _redis.Get(key);
    var result = JsonSerializer.Deserialize<PersonStruct>(Encoding.UTF8.GetString(getBytes));
    

    Seems it’s serializing structs by calling ToString()

    Login or Signup to reply.
  2. The differences with Struct’s is that they’re treated like a single scalar value, where instead of serializing every property of a struct value, e.g. Date, Day, DayOfWeek, DayOfYear, Hour, etc in the case of a DateTime, only a single scalar value is serialized for DateTime’s, TimeSpan’s, etc.

    ServiceStack.Text serializers does this by convention where it will attempt to use ToString() to serialize into a single string value and the TStruct(string) constructor to deserialize the value. Alternatively you can provide your own deserializer function with a static ParseJson() method.

    So if you want to deserialize structs you would need to provide a serializer/deserializer for your Struct by overriding ToString() and providing a string constructor, e.g:

    public struct PersonStruct
    {
        public PersonStruct(string jsonStr)
        {
            var str = jsonStr.FromJson<string>();
            Year = int.Parse(str.LeftPart(','));
            Name = str.RightPart(',');
        }
            
        public string Name { get; set; }
        public int Year { get; set; }
        
        public override string ToString() => Year + "," + Name;
    }
    

    Then you’ll be able to use it in ServiceStack.Redis Typed APIs as seen in this Gistlyn example gist.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search