C# 如何获取 CookieContainer 的所有 Cookie?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15983166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get all Cookies of a CookieContainer?
提问by christophrus
I want to export a CookieContainer to JSON using Newtonsoft.Json but unfortunately CookieContainer hasn't an enumerator or stuff, so I can't cycle through it ...
我想使用 Newtonsoft.Json 将 CookieContainer 导出到 JSON,但不幸的是 CookieContainer 没有枚举器或其他东西,所以我无法循环遍历它......
Edit:With my posted solution it would be something like this:
编辑:使用我发布的解决方案,它会是这样的:
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();
}
采纳答案by christophrus
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;
}
回答by Ivan Popov
The first answer did not work for a portable project. So here's option 2, also uses reflection
第一个答案不适用于便携式项目。所以这里的选项 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) I also tried
1)我也试过
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.
2)您可以遍历domains.Keys并对所有键使用container.GetCookies()。但是我遇到了问题,因为 GetCookies 需要 Uri 而不是我所有的键都匹配 Uri 模式。
回答by Andre Andersen
This method will ensure to get all cookies, no matter what the protocol is:
无论协议是什么,此方法都将确保获取所有 cookie:
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;
}
}
}
}
回答by Boris Zinchenko
Use CookieContainer.GetCookies Method
使用CookieContainer.GetCookies 方法
CookieCollection cookies = cookieContainer.GetCookies(new Uri(url));
where url
is URL of your site.
url
您网站的网址在哪里。
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.
就我而言,正如其他答案中所建议的那样,我无法使用反射。但是,我确实知道要查询的站点的 URL。我认为容器不会盲目地返回所有 cookie 而是按 URL 返回它们甚至是合乎逻辑的,因为 cookie 始终属于特定的 URL,并且不能在与其关联的域的上下文之外使用。