【问题标题】:MVC4 and ServiceStack session in RedisRedis 中的 MVC4 和 ServiceStack 会话
【发布时间】: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


【解决方案1】:

因为 AuthUserSession 是一个 DataContract 并且属性现在在 v4 中被继承,你还需要用[DataMember] 标记每个成员,例如:

public class CustomUserSession : AuthUserSession
{
    [DataMember]
    public string Hello { get; set; }
}   

【讨论】:

  • 天哪,我现在觉得很傻。那行得通,谢谢。我现在也看到文档实际上说明了这一点 - 不知道我是怎么错过的。
猜你喜欢
  • 1970-01-01
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
  • 1970-01-01
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多