首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何获取CookieContainer的所有Cookie?

如何获取CookieContainer的所有Cookie?
EN

Stack Overflow用户
提问于 2013-04-13 09:21:29
回答 4查看 36.3K关注 0票数 27

我想使用Newtonsoft.Json将CookieContainer导出到JSON,但不幸的是CookieContainer没有枚举器之类的东西,所以我无法遍历它……

编辑:对于我发布的解决方案,应该是这样的:

代码语言:javascript
复制
private static void Main(string[] args)
{
    CookieContainer cookieContainer = new CookieContainer();
    cookieContainer.Add(new Cookie("name1", "value1", "/", ".testdomain1.com"));
    cookieContainer.Add(new Cookie("name2", "value1", "/path1/", ".testdomain1.com"));
    cookieContainer.Add(new Cookie("name2", "value1", "/path1/path2/", ".testdomain1.com"));
    cookieContainer.Add(new Cookie("name1", "value1", "/", ".testdomain2.com"));
    cookieContainer.Add(new Cookie("name2", "value1", "/path1/", ".testdomain2.com"));
    cookieContainer.Add(new Cookie("name2", "value1", "/path1/path2/", ".testdomain2.com"));

    CookieCollection cookies = GetAllCookies(cookieContainer);

    Console.WriteLine(JsonConvert.SerializeObject(cookies, Formatting.Indented));
    Console.Read();
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-04-14 02:01:03

使用反射的解决方案:

代码语言:javascript
复制
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;
}

.NET 6更新

最后,.NET 6发布了,并引入了提取CookieCollection - Documentation linkCookieContainer.GetAllCookies()方法。

代码语言:javascript
复制
public System.Net.CookieCollection GetAllCookies();
票数 24
EN

Stack Overflow用户

发布于 2015-08-09 11:42:46

此方法将确保获得所有cookies,无论协议是什么:

代码语言:javascript
复制
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;
            }
        }
    }
}
票数 15
EN

Stack Overflow用户

发布于 2015-05-06 23:10:38

第一个答案不适用于可移植项目。所以这里是选项2,也使用反射

代码语言:javascript
复制
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)我也试过了

代码语言:javascript
复制
var domainTableField = container.GetType().GetRuntimeField("m_domainTable"); 

但它返回null。

2)您可以遍历domains.Keys并对所有键使用container.GetCookies()。但我在这方面遇到了问题,因为GetCookies需要Uri,但并不是所有的键都与Uri模式匹配。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15983166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档