我想使用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();
}
发布于 2013-04-14 02:01:03
使用反射的解决方案:
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 link的CookieContainer.GetAllCookies()
方法。
public System.Net.CookieCollection GetAllCookies();
发布于 2015-08-09 11:42:46
此方法将确保获得所有cookies,无论协议是什么:
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;
}
}
}
}
发布于 2015-05-06 23:10:38
第一个答案不适用于可移植项目。所以这里是选项2,也使用反射
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模式匹配。
https://stackoverflow.com/questions/15983166
复制相似问题