【问题标题】:Session timeout different just for one variable会话超时仅对一个变量不同
【发布时间】:2014-03-25 08:24:42
【问题描述】:

cookies中,我们可以使用Expires (http://msdn.microsoft.com/en-us/library/system.net.cookie.expires%28VS.80%29.aspx) 来定义过期日期。

在 .Net 4.0 (MVC) 中,是否可以为一个变量定义不同的 会话 超时?

我真的不喜欢有类似的东西:

session["VariableCreatedOn"] = DateTime.Now()
session["VariableValue"] = xxx

然后尝试验证 VariableCreatedOn 是否早于 XYZ。

默认情况下有解决方案吗?

【问题讨论】:

标签: c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


【解决方案1】:

没有内置的方法,但是你可以很简单地实现它:

Session[name] = value;

//now add a cleanup task that will run after the specified interval
Task.Delay(expireAfter).ContinueWith((task) => {
    Session.Remove(name);
});

我将它包装成一个非常方便的“会话扩展器”类here 像这样使用它:

//store and expire after 5 minutes
Session.AddWithTimeout("key", "value", TimeSpan.FromMinutes(5));

PS。如果您仍在使用旧的 .NET 版本(没有异步代码,没有任务),您也可以在链接下找到兼容的版本。

【讨论】:

  • 谢谢 :) 我会检查你的博客。
  • 在 MVC 5 中似乎不起作用。一旦 Delay 过去,Session 就是 null。所以看起来闭包没有捕获Session。我错过了什么吗? ** 编辑:将Session 分配给局部变量似乎可以纠正。
【解决方案2】:

不,不可能在会话的其余部分继续存在时直接让一个会话变量过期,反之亦然。

虽然不必到处检查值是否已过期,您可以将此逻辑包装在自定义类中并将该类的对象存储在会话中(而不是存储值和到期日期或创建日期作为两个单独的值)。

它的工作方式类似于可空值类型,因为您在该类上有一个 Value 属性,并且该属性的 getter 将根据内部 CreationDate 属性的值返回一个值或返回 null。

下面是未经测试的代码;根据您的具体需求进行调整。

public class ExpiringSessionValue<T>
{
    private T _value;
    private DateTime _created = DateTime.Now;

    public ExpiringSessionValue(T value)
    {
        _value = value;
    }

    public T Value
    {
        get
        {
            if (_created >= DateTime.Now.AddMinutes(-10))
                return _value;
            else
                return default(T);
        }
    }
}

【讨论】:

  • 您可以存储预先计算的“到期”日期,而不是 _created。如果您经常获得价值,这将为重复的AddMinutes 节省几纳秒。
猜你喜欢
  • 2014-08-27
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 2012-03-08
  • 1970-01-01
  • 2014-05-15
相关资源
最近更新 更多