views:

570

answers:

3

I have the following code which re-uses a CookieContainer which logs in on the first request, but just uses the cookie container for requests after.

After a period of time if idle the site will give a Session Timeout, I will need to perform the login again.

Q: Can I determine (with the cookie container object) if the timeout has happened or is it best to determine if it has happened from the HttpWebResponse which happens to contains text like 'session timeout'. What is the best way to do this?

        private static CookieContainer _cookieContainer;
    private static CookieContainer CurrentCookieContainer
    {
        get
        {
            if (_cookieContainer == null || _cookieContainer.Count == 0)
            {
                lock (_lock)
                {
                    if (_cookieContainer == null || _cookieContainer.Count == 0)
                    {
                        //_cookieContainer.GetCookies(
                        _cookieContainer = DoLogin();
                    }
                }
            }

            return _cookieContainer;
        }
        set
        {
            _cookieContainer = value;
        }
    }

And then this method calls out to the container:

        public static string SomeMethod(SomeParams p)
        {
            HttpWebRequest request_thirdPartyEnquiryDetails = (HttpWebRequest)WebRequest.Create(thirdPartyEnquiryDetails);
            CookieContainer cookieContainer = CurrentCookieContainer;
            request_thirdPartyEnquiryDetails.CookieContainer = cookieContainer;
//... and it goes on to submit a search and return the response
        }
+2  A: 

Well, since the timeout is 30 mins, I have set the login to repeat after 25 mins.

private static DateTime? lastLoggedIn;

    private static CookieContainer _cookieContainer;
    private static CookieContainer CurrentCookieContainer
    {
        get
        {
            if (_cookieContainer == null || _cookieContainer.Count == 0 || !lastLoggedIn.HasValue || lastLoggedIn.Value.AddMinutes(25) < DateTime.Now)
            {
                lock (_lock)
                {
                    if (_cookieContainer == null || _cookieContainer.Count == 0 || !lastLoggedIn.HasValue || lastLoggedIn.Value.AddMinutes(25) < DateTime.Now)
                    {
                        _cookieContainer = DoLogin();
                        lastLoggedIn = DateTime.Now;
                    }                        
                }
            }

            return _cookieContainer;
        }
        set
        {
            _cookieContainer = value;
        }
    }

As an extra precaution, I check the HttpResponse for the text which returns when the page session times out (although its now expected this won't be seen). If this happens I set the lastLoggedIn date to null and run the search method again.

CRice
This should work, but remember that you may be logged out even if your cookie hasn't expired
Rune Grimstad
+1  A: 

You can extract all cookies for a domain using the CookieContainer.GetCookies(string uri) method. Using this CookieCollection you can get the cookie you are interested in and check its Expired property to see if it has expired.

There is one thing you should note: Your session may end even if your cookie is valid. IIS may restart the app domain the web application runs in and in that case all authenticated users may loose their session data. So checking the cookie is generally not enough to ensure that you stay logged in.

Rune Grimstad
Ok, thanks again
CRice
A: 

Hi,

I am not sure what you want to achieve, but you should notice that CookieContainer has a bug on .Add(Cookie) and .GetCookies(uri) method.

See the details and fix here:

http://dot-net-expertise.blogspot.com/2009/10/cookiecontainer-domain-handling-bug-fix.html

CallMeLaNN