ServiceStack Redis缓存未按预期进行序列化

3
我们的项目中有一个类,包含缓存信息:
public class SOLECache
{
    public DateTime CreatedDTM { get; set; }
    public int UserID { get; set; }
    public int MaxAgeSeconds { get; set; }
    public object Data { get; set; }
}

属性Data保存我们想要缓存的对象,可以是任何类型。由于我们有一个具有多个Web服务器的生产环境,我们正在尝试使用Redis和ServiceStack来处理缓存。现在缓存已经正确地存储在Redis服务器上,并且这部分工作正常。问题在于当我们尝试获取缓存时:

 _cacheClient.Get<AppUser>("someCacheKey");

我们的Data属性总是返回NULL值。所以基本上很明显,数据存储在Redis服务器下正确的键下,但当我们检索它时,我们得到除了Data属性之外的所有内容,而Data属性始终为NULL。
有人可以给我一些见解吗?这可能是因为我们在Data属性中存储的对象具有一些只读属性和一些方法-它不是一个干净的POCO吗?以下是被存储对象的示例结构:
public class AppUser
{ 
   public int UserId {get; set;}
   public string FirstName {get; set;}
   public string LastName {get; set;}
   public string FullName
   {
      get {
         return FirstName + " " + LastName;
      }
   }
   public void DoSomething()
   {
      // some method logic here...
   }
}

这个类是否会导致ServiceStack.RedisClient无法正确序列化AppUser实例?

我们在Redis中设置缓存的方式是:

_cacheClient.Set("someCacheKey", soleCache, DateTime.UtcNow.AddSeconds(soleCache.MaxAgeSeconds))

其中soleCache是一个已填充Data属性的SOLECache实例。存储在Redis中的数据如下:

{"CreatedDTM":"2013-06-28T13:45:56.5091664-04:00","UserID":123,"MaxAgeSeconds":60,"Data":{"FullName":"John M Doe","FirstName":"John","MiddleName":"M","LastName":"Doe","Email":"me@here.com","BackupEmail":"me@there.com","GradYear":null,"PostalCode":"12345     ","Location":"12345     ","City":null,"IsValid":true,"Active":true,"AccessLevel":10,"CurrentApp":0,"CurrentURL":"http://localhost:4387/","RequestMethod":"GET","IsMobile":false,"IsInApp":false,"ServerName":"ITSWEB-JMDOE","ID":40117,"IsAdmin":true,"Theme":"basic","ExpirationDT":null,"WebFolderName":"jmdoe","ProgramCD":null,"BranchCD":"MBIM","RoleOverride":0,>"CurrentAppRoleID":0,"EnableNativeMailFLG":false,"PasswordStatus":"GOOD","CampusCD":"M","Campus":"Smallville","DisclaimerDate":"2012-07-02T10:55:54.297","SecurityQuestion":null,"ClassificationMSK":4,"IsLinkedToCurrentApp":false,"IsBlockedFromCurrentApp":false,"IsBlockedMessageText":null,"CurrentAppRoleName":null,"AssignedAppRoleID":0,"AppSmallGroup":0,"PermissionsArray":[],"AdminPermissionsArray":[],"ViewLevel":[],"LastLoginDTM":"2013-06-27T16:28:23.21","Session":{"SessionID":"1923dac2-f3af-4dc5-ad51-7202fc077ba3","SessionCreatedDTM":"2013-06-28T09:03:13.12","SessionTimeout":60,"SessionUserID":40117,"SessionCurrentApp":0,"SessionLastViewDTM":"2013-06-28T13:24:37.69","SessionUserAgent":"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36","SessionIP":"127.0.0.1","SessionLastURL":"http://localhost:4387/Home/CacheInfo","SessionServer":"ITSWEB-JMDOE","LastLoginDTM":null,"SessionLoginMethod":null,"ADUserName":null,"ADPassword":null,"Errors":{},"HasErrors":false,"ModelState":{}},"CurrentInstanceID":0,"CurrentPageHasNotes":false,"CurrentPageIsFavorited":false,"BrowserBrand":"Chrome","BrowserVersion":"28.0","BrowserPlatform":"Windows 8","BrowserValid":true,"Favorites":[],"FullNameWithEmail":"John M Doe (jmdoe@here.com)","FullNameWithoutMiddleName":"John Doe","IsStudent":true,"Errors":{},"HasErrors":false,"ModelState":{}}}

我们已经追踪到问题出现在ServiceStack.Text.JsonSerializer方法上,由于某种原因,它无法正确地对该对象进行序列化。当我们将此方法替换为NewtonSoft的Json Serializer时,它可以正常工作...似乎是ServiceStack的问题,但我可能错了...

不太明白这个问题...你是如何将数据插入缓存中的?_cacheClient.Set<SOLEcache>("someCacheKey", AppUserObject)。Redis 中的字符串是什么样子的? - paaschpa
@paaschpa,请查看我在问题中提供的附加信息。 - Marko
1个回答

1
我们的Data属性总是得到一个NULL值。 因此,看起来您正在将一个类型为SOLECache的对象(来自问题:其中soleCache是具有填充的Data属性的SOLECache实例。)插入缓存中。 而且,您想要从缓存中获取类型为AppUser的数据(来自问题:_cacheClient.Get<AppUser>("someCacheKey");) 也许这只是一个打字错误(我没有在AppUser上看到一个Data属性),但切换类型可能是问题所在。
您应该能够将类型为SOLECache的对象插入缓存并获取类型为SOLECache的对象。只要您设置了JsConfig.ExcludeTypeInfo = false;(这是默认值),它就应该使用正确的类型填充Data属性。看起来您可能已经设置了JsConfig.ExcludeTypeInfo = true;,因为我在存储在Redis中的数据中没有看到__type字段(这是ServiceStack.Text如何知道Data对象的类型)。如果您排除了TypeInfo,则反序列化缓存数据应该会用JSON字符串填充Data属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接