【发布时间】:2014-02-25 14:22:47
【问题描述】:
我有一个全新的 MVC4 项目,我在该项目上安装了 ServiceStack MVC 启动包(MyGET 的 4.0.12 版)来引导服务堆栈会话的使用。
在我的AppHost 中,我的自定义会话配置为:
Plugins.Add(new AuthFeature(() => new CustomUserSession(),
new IAuthProvider[] {
new CredentialsAuthProvider(config)
}));
出于测试目的,自定义会话如下所示:
public class CustomUserSession : AuthUserSession
{
public string Hello { get; set; }
}
并且ICacheClient被注册为redis客户端:
// register the message queue stuff
var redisClients = config.Get("redis-servers", "redis.local:6379").Split(',');
var redisFactory = new PooledRedisClientManager(redisClients);
var mqHost = new RedisMqServer(redisFactory, retryCount: 2);
container.Register<IRedisClientsManager>(redisFactory); // req. to l
container.Register<IMessageFactory>(mqHost.MessageFactory);
container.Register<ICacheClient>(c =>
(ICacheClient)c.Resolve<IRedisClientsManager>()
.GetCacheClient())
.ReusedWithin(Funq.ReuseScope.None);
然后我创建了一个ControllerBase,为简单起见,它会为每个请求加载并保存自定义会话:
public abstract class ControllerBase : ServiceStackController<CustomUserSession>
{
protected override IAsyncResult BeginExecute (System.Web.Routing.RequestContext requestContext, AsyncCallback callback, object state)
{
ViewBag.Session = this.UserSession;
return base.BeginExecute (requestContext, callback, state);
}
protected override void EndExecute(IAsyncResult asyncResult)
{
SaveSession(null);
base.EndExecute(asyncResult);
}
public void SaveSession(TimeSpan? expiresIn = null)
{
Cache.CacheSet(SessionFeature.GetSessionId(), UserSession, expiresIn ?? new TimeSpan(0, 30, 0));
}
}
然后我在我的一个操作中修改Hello 属性以读取“World”,并且我可以清楚地看到SaveSession 方法上的断点,该值已正确。但是,在再次加载页面并检查加载的会话时,没有设置任何内容。此外,查看 Redis 数据库,保存了以下 blob:
{
"createdAt": "/Date(-62135596800000-0000)/",
"lastModified": "/Date(-62135596800000-0000)/",
"providerOAuthAccess": [],
"isAuthenticated": true,
"tag": 0
}
它没有保存我的自定义属性。谁能告诉我我做错了什么/错过了什么?
=== 更新 ===
如果我从基础 AuthUserSession 更改任何属性,对这些属性的更改将被保留 - 所以看起来 SS 不知何故决定忽略我的具体类型中的属性。 p>
【问题讨论】:
-
我在我的 SS 服务中使用 SaveSession Extension 方法。 ServiceStackController中不存在,但是看里面的代码(github.com/ServiceStack/ServiceStack/blob/master/src/…) var sessionKey = SessionFeature.GetSessionKey(httpReq.GetSessionId());我只是好奇你的方法和这个方法是否为会话密钥返回相同的值?
-
您是否使用 Redis 中的“monitor”命令来监视所有更改,以查看您的属性是否在任何时间点保持不变?我很好奇它是否被设置然后由于某种原因被覆盖?
-
redis monitor 命令的绝妙技巧。这验证了必须使用您在第一条评论中提供的 GetSessionKey - 而不仅仅是 sessionId。我还可以通过 redis monitor cmd 看到我的属性从不发送到 redis 服务器,所以我开始相信它要么是 SS 中的错误,要么是我这边的错误配置。
标签: c# asp.net-mvc-4 servicestack