我们的项目中有一个包含缓存信息的类:
public class SOLECache
{
public DateTime CreatedDTM { get; set; }
public int UserID { get; set; }
public int MaxAgeSeconds { get; set; }
public object Data { get; set; }
}
where属性Data保存我们想要缓存的对象,可以是任何类型。因为我们有一个包含多个Web服务器的生产环境,所以我们尝试使用Redis和ServiceStack来处理缓存。现在缓存已正确存储在Redis服务器上,该部分工作正常。问题在于,当我们尝试获取缓存时:
_cacheClient.Get<AppUser>("someCacheKey");
我们总是为Data属性获取NULL值。所以基本上很明显,数据是在正确的密钥下存储在Redis服务器上的,但是当我们检索它时,除了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是SOLECache的一个实例,带有填充的Data属性。存储在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的问题,但我可能错了......
答案 0 :(得分:1)
我们总是为Data属性获取NULL值。
因此,看起来您正在向缓存中插入SOLECache
类型的对象(来自问题:其中soleCache是SOLECache的实例,带有填充的数据属性。)
并且,您希望将数据从缓存中提取到类型AppUser
(来自问题: _cacheClient.Get<AppUser>("someCacheKey");
)
也许这只是一个错字(我没有看到AppUser
上的数据属性),但切换类型可能是问题。
您应该能够插入缓存类型SOLECache
并输出类型SOLECache
。只要您有JsConfig.ExcludeTypeInfo = false;
(这是默认值),它就应该使用正确的类型填充Data属性。看起来你可能有JsConfig.ExcludeTypeInfo = true;
因为我没有在Redis中存储的数据中看到__type
字段(这就是ServiceStack.Text知道Data对象的类型)。如果要排除TypeInfo,则反序列化缓存数据应使用JSON字符串填充Data属性。