如何获取CookieContainer的所有Cookie?

我想使用Newtonsoft.Json将CookieContainer导出为JSON,但遗憾的是CookieContainer没有枚举器或东西,所以我不能循环使用它…

编辑:使用我发布的解决方案,它将是这样的:

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(); } 

使用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; } 

第一个答案对便携式项目不起作用。 所以这里的选项2,也使用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)我也试过了

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

但它返回null。

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

无论协议是什么,此方法都将确保获取所有cookie:

 public static IEnumerable 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; } } } } 

使用CookieContainer.GetCookies方法

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

其中url是您网站的url。

就我而言,我无法使用reflection,正如其他答案中所建议的那样。 但是,我确实知道要查询的网站的URL。 我认为容器不会盲目地返回所有cookie但是每个URL返回它们是合乎逻辑的,因为cookie总是属于特定的URL,不能在与它们相关的域的上下文之外使用。