How can I get all Cookies of a CookieContainer?

坚强是说给别人听的谎言 提交于 2019-11-27 04:48:36

A solution using reflection:

public static CookieCollection GetAllCookies(CookieContainer cookieJar)
{
    CookieCollection cookieCollection = new CookieCollection();

    Hashtable table = (Hashtable) cookieJar.GetType().InvokeMember("m_domainTable",
                                                                    BindingFlags.NonPublic |
                                                                    BindingFlags.GetField |
                                                                    BindingFlags.Instance,
                                                                    null,
                                                                    cookieJar,
                                                                    new object[] {});

    foreach (var tableKey in table.Keys)
    {
        String str_tableKey = (string) tableKey;

        if (str_tableKey[0] == '.')
        {
            str_tableKey = str_tableKey.Substring(1);
        }

        SortedList list = (SortedList) table[tableKey].GetType().InvokeMember("m_list",
                                                                    BindingFlags.NonPublic |
                                                                    BindingFlags.GetField |
                                                                    BindingFlags.Instance,
                                                                    null,
                                                                    table[tableKey],
                                                                    new object[] { });

        foreach (var listKey in list.Keys)
        {
            String url = "https://" + str_tableKey + (string) listKey;
            cookieCollection.Add(cookieJar.GetCookies(new Uri(url)));
        }
    }

    return cookieCollection;
}

The first answer did not work for a portable project. So here's option 2, also uses reflection

using System.Linq;
using System.Collections;
using System.Reflection;
using System.Net;

    public static CookieCollection GetAllCookies(this CookieContainer container)
    {
        var allCookies = new CookieCollection();
        var domainTableField = container.GetType().GetRuntimeFields().FirstOrDefault(x => x.Name == "m_domainTable");            
        var domains = (IDictionary)domainTableField.GetValue(container);

        foreach (var val in domains.Values)
        {
            var type = val.GetType().GetRuntimeFields().First(x => x.Name == "m_list");
            var values = (IDictionary)type.GetValue(val);
            foreach (CookieCollection cookies in values.Values)
            {
                allCookies.Add(cookies);                    
            }
        }          
        return allCookies;
    }

1) I also tried

var domainTableField = container.GetType().GetRuntimeField("m_domainTable"); 

but it returned null.

2) You can iterate through domains.Keys and use container.GetCookies() for all keys. But I've had problems with that, because GetCookies expects Uri and not all my keys matched Uri pattern.

This method will ensure to get all cookies, no matter what the protocol is:

public static IEnumerable<Cookie> GetAllCookies(this CookieContainer c)
{
    Hashtable k = (Hashtable)c.GetType().GetField("m_domainTable", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(c);
    foreach (DictionaryEntry element in k)
    {
        SortedList l = (SortedList)element.Value.GetType().GetField("m_list", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(element.Value);
        foreach (var e in l)
        {
            var cl = (CookieCollection)((DictionaryEntry)e).Value;
            foreach (Cookie fc in cl)
            {
                yield return fc;
            }
        }
    }
}

Use CookieContainer.GetCookies Method

CookieCollection cookies = cookieContainer.GetCookies(new Uri(url));

where url is URL of your site.

In my case, I was not able to use reflection, as suggested in other answers. However, I did know URL of my site to query. I think it is even logical that container does not return all cookies blindly but returns them per URL because cookies always belong to a particular URL and cannot be used outside of context of the domain associated with them.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!