An extension class of CookieContainer

Recently, the cookies returned by the server are frequently used in the project. Because the project uses HttpClient and uses Cookie container to automatically host cookies, it is not convenient to obtain cookies. So I wrote an extension class.

 

First, traverse to get all the cookies, then store them in the dictionary, and then store the dictionary in the memory cache. When the method is called next time, first judge whether there is any in the cache, and then traverse again if there is No. When the number of cookiecontainers changes, they will also be reassigned

  

  

    public static class CookieParser
    {
        public static ObjectCache Cache = MemoryCache.Default;

        private static T Get<T>(this ObjectCache cache,string key)
        {
            return (T)cache.Get(key);
        }

        /// <summary>
        /// Increase cache
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="key"></param>
        /// <param name="obj"></param>
        /// <param name="timeout">Cache expiration time in minutes, 30 minutes by default</param>
        /// <returns></returns>
        private static bool Add(this ObjectCache cache,string key, object obj, int timeout=30)
        {
            return Cache.Add(key, obj, DateTime.Now+TimeSpan.FromMinutes(timeout));
        }

        private static readonly object Lock = new object();

        public static string GetCookieValue(this CookieContainer cc,string name)
        {
            return cc.GetCookie(name).Value;
        }

        public static Cookie GetCookie(this CookieContainer cc, string name)
        {
            var key = AddOrUpdateCache(cc);
            return Cache.Get<Dictionary<string, Cookie>>(key)["name"];
        }

        public static List<Cookie> GetAllCookie(this CookieContainer cc)
        {
            var key = AddOrUpdateCache(cc);
            return Cache.Get<Dictionary<string, Cookie>>(key).Values.ToList();
        }

        private static string AddOrUpdateCache(CookieContainer cc)
        {
            var key = cc.GetHashCode().ToString();
            lock (Lock)
            {
                if (!Cache.Contains(key))
                {
                    Cache.Add(key, cc.Parser());
                }
                else if(Cache.Get<Dictionary<string,Cookie>>(key).Count!=cc.Count)//Quantity change, update object
                {
                    Cache[key] = cc.Parser();
                }
            }
            return key;
        }

        private static Dictionary<string, Cookie> Parser(this CookieContainer cc)
        {
            var table = (Hashtable)cc.GetType().InvokeMember("m_domainTable",
                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField |
                System.Reflection.BindingFlags.Instance, null, cc, new object[] { });

            return (
                from object pathList
                    in table.Values
                select (SortedList)pathList.GetType().InvokeMember("m_list", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, pathList, new object[] { }) into lstCookieCol
                from CookieCollection colCookies in lstCookieCol.Values
                from Cookie c in colCookies
                select c)
                .ToDictionary(c => c.Name, c => c);
        }
    }

Keywords: C#

Added by benjy on Fri, 01 May 2020 12:27:32 +0300