tags:

views:

318

answers:

6

I like to create a session value that expires in 5 minutes.

How to do that, do I need to manually compare creation time when I read it?

Session("sessionval") = myvariable
Session("sessioncreated") = now
+3  A: 

you can not define custom timeout to a session variable.

Maybe you can use cache for this, with a unique key dependent to session.

You can set timeout to a cached item.

Cache.Insert("key_dependent_to_session", value, Nothing, 
  DateTime.Now.AddMinutes(5), TimeSpan.Zero)
Canavar
Take it a little further create a couple of static (Shared in VB parlance?) accessor methods of a static (Shared) class. Have those methods discover the current session ID and do some suffixing of the key name.
AnthonyWJones
+2  A: 

That is correct. Session state doesn't have an Expiration concept.

If your data are not per-user, you can use Cache instead. You could even use Cache, but include the user name as part of the key, which would sort of give you an expiring session state.

John Saunders
Even it is is session specfic you could use the session ID as part of the key.
AnthonyWJones
@John: "Session state doesn't have an Expiration concept." How do you explain that statement given the timeout attribute of the sessionState object?
Cerebrus
.Timeout is for the entire session state, it's not a per-item expiration.
John Saunders
+6  A: 

If you are asking how to do it on a single variable I do not think it is possible, but you can define the session timeout period using the web.config

<system.web>  
    <sessionState timeout="5" />
<system.web>

this would affect all of your session objects, not just a single one.

My suggestion for giving a custom expiration date to a single item is to create a cookie, that way you can actually set it's expiration value.

Response.Cookies.Add(New Web.HttpCookie("AdminID", admin.AdminID))
Response.Cookies("AdminID").Expires = Now.AddMinutes(5)
TheTXI
@Anthony: that's why I specifically said in the answer that if you are asking how to do it in a single item I do not think it can be done.
TheTXI
@TheTXI it is an option and the warning is on the box. I would not personally choose this option(web.config) but it is perfectly valid answer +1
cgreeno
BTHB: I would not personally choose it either, but given the lack of fine detail as to what the OP is wanting to do, it was a possibility however remote.
TheTXI
@TheTXI: Your additional suggestion now has the flaw that the burden of holding the value placed on the client and bandwidth needed to include it in all requests whether required or not, in addition to reducing its type to a string. Not mention that clients could block or worse spoof them.
AnthonyWJones
@Anthony, notwithstanding the above obvious flaws, cookies are still used commonly. It remains upto the OP to choose the best possible solution for his/her context. I must admit that the cookie solution didn't even occur to me. Definitely, +1.
Cerebrus
A: 

1) Put this in web.config

<configuration>
   <system.web>
     <sessionState mode="InProc" timeout="5">
     </sessionState>
   </system.web> 
</configuration>

2) Set System.Web.SessionState.HttpSessionState.Timeout = 5 mins.

nils_gate
+1  A: 

I tend to agree with TheTXI.

Although a single Session item cannot be assigned a custom timeout, you should note that in InProc session mode, Sessionstate is itself added as an item to the ASP.NET cache. This enables it to have a "timeout".

In your particular scenario, a Cache object is the best suited solution.

Cerebrus
-1. To be consistent. The question is not about expiration of the whole session state.
AnthonyWJones
@Anthony: You sure are liberal with the downvotes and assumptions as to what the original author is looking for, especially for someone who never even bothered to post his own answer.
TheTXI
+3  A: 

If you want to use the SessionState you could create your own wrapper so instead of caching the actual item, you can cache the wrapper. Here is a quick dirty untested example of a wrapper that checks if the item is null, or if it has expired it will call a Func that you can provide a refreshed item.

The Func takes the last set value so if you can determine if the value is still valid you could avoid reloading it.

public class TimeExpirationItem<T>
{
    private T _item=default(T);
    private TimeSpan _expirationDuration;
    private Func<T> _getItemFunc;
    private DateTime _expiresTime;
    public TimeExpirationItem(TimeSpan expirationDuration, Func<T, T> getItemFunc)
    {
        this._getItemFunc = getItemFunc;
        this._expirationDuration = expirationDuration;
    }
    public T Item
    {
        get
        {
            if (_item == null || ItemIsExpired())
            {
                _item = _getItemFunc(_item);
                _expiresTime = DateTime.Now.Add(_expirationDuration);
            }
            return _item;
        }
    }
    public bool ItemIsExpired()
    {
        return DateTime.Now > _expiresTime;
    }
}

Again this code is provided as is with no warranty and it is untested but is an example of the things you can do.

Using it would be something like the following:

Session.Add("ObjectKey",new TimeExpirationItem<MyObject>(new TimeSpan(0,0,5),mo=>MyObjectRepository.GetItemByLogin(Request.User.Identity.Name));

JoshBerke
Great solution man!
Sam Schutte
Thanks much:-)..
JoshBerke