如何在CookieContainer中获取cookie信息? (所有这些,不是针对特定领域)

时间:2012-12-02 23:30:04

标签: c# cookies .net-4.0 httpwebrequest httpwebresponse

请参阅以下代码:

CookieContainer cookieJar = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://www.google.com");
request.CookieContainer = cookieJar;

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
int cookieCount = cookieJar.Count;

如何在cookieJar内获取Cookie信息? (所有这些,不仅仅针对特定领域。)
我怎样才能添加或删除cookie呢?

6 个答案:

答案 0 :(得分:14)

反射可用于获取包含CookieContainer对象中所有域密钥的私有字段

问。我如何得到该私人领域的名称?

答。使用Reflector;

它被声明为:

private Hashtable m_domainTable;

一旦我们获得私有字段,我们将获得域密钥,然后获取cookie是一个简单的迭代。

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

namespace ConsoleApplication4
{


    static class Program
    {

        private static void Main()
        {

            CookieContainer cookies = new CookieContainer();
            cookies.Add(new Cookie("name1", "value1", "/", "domain1.com"));
            cookies.Add(new Cookie("name2", "value2", "/", "domain2.com"));

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



            foreach (var key in table.Keys)
            {
                foreach (Cookie cookie in cookies.GetCookies(new Uri(string.Format("http://{0}/", key))))
                {
                    Console.WriteLine("Name = {0} ; Value = {1} ; Domain = {2}", cookie.Name, cookie.Value,
                                      cookie.Domain);
                }
            }


            Console.Read();
        }

    }

}

答案 1 :(得分:7)

感谢AppDeveloper的回答,这是一个稍微修改过的版本作为扩展方法。

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

public static class CookieContainerExtension
{
    public static List<Cookie> List(this CookieContainer container)
    {
        var cookies = new List<Cookie>();

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

        foreach (var key in table.Keys)
        {

            Uri uri = null;

            var domain = key as string;

            if (domain == null)
                continue;

            if (domain.StartsWith("."))
                domain = domain.Substring(1);

            var address = string.Format("http://{0}/", domain);

            if (Uri.TryCreate(address, UriKind.RelativeOrAbsolute, out uri) == false)
                continue;

            foreach (Cookie cookie in container.GetCookies(uri))
            {
                cookies.Add(cookie);
            }
        }

        return cookies;
    }
}

要获取列表,只需在CookieContainer上调用List():

CookieContainer cookies = new CookieContainer();
cookies.Add(new Cookie("name1", "value1", "/", "www.domain1.com"));
cookies.Add(new Cookie("name2", "value2", "/", "www.domain2.com"));
List<Cookie> cookieList = cookies.List();

答案 2 :(得分:5)

这些答案都不适合我。这是我解决问题的简单方法。

public static List<Cookie> List(this CookieContainer container)
{
    var cookies = new List<Cookie>();

    var table = (Hashtable)container.GetType().InvokeMember("m_domainTable",
        BindingFlags.NonPublic |
        BindingFlags.GetField |
        BindingFlags.Instance,
        null,
        container,
        null);

    foreach (string key in table.Keys)
    {
        var item = table[key];
        var items = (ICollection) item.GetType().GetProperty("Values").GetGetMethod().Invoke(item, null);
        foreach (CookieCollection cc in items)
        {
            foreach (Cookie cookie in cc)
            {
                cookies.Add(cookie);
            }
        }
    }

    return cookies;
}           

答案 3 :(得分:4)

改进版PaRiMal RaJ的代码。此方法将打印http和https cookie。准备将它粘贴到你的班级。

    // Paste this dependencies in your class
    using System;
    using System.Net;
    using System.Linq;
    using System.Reflection;
    using System.Collections;
    using System.Collections.Generic;

    /// <summary>
    /// It prints all cookies in a CookieContainer. Only for testing.
    /// </summary>
    /// <param name="cookieJar">A cookie container</param>
    public void PrintCookies (CookieContainer cookieJar)
    {
        try
        {
            Hashtable table = (Hashtable) cookieJar
                .GetType().InvokeMember("m_domainTable",
                BindingFlags.NonPublic |
                BindingFlags.GetField |
                BindingFlags.Instance,
                null,
                cookieJar,
                new object[] {});


            foreach (var key in table.Keys)
            {
                // Look for http cookies.
                if (cookieJar.GetCookies(
                    new Uri(string.Format("http://{0}/", key))).Count > 0)
                {
                    Console.WriteLine(cookieJar.Count+" HTTP COOKIES FOUND:");
                    Console.WriteLine("----------------------------------");
                    foreach (Cookie cookie in cookieJar.GetCookies(
                        new Uri(string.Format("http://{0}/", key))))
                    {
                        Console.WriteLine(
                            "Name = {0} ; Value = {1} ; Domain = {2}", 
                            cookie.Name, cookie.Value,cookie.Domain);
                    }
                }

                // Look for https cookies
                if (cookieJar.GetCookies(
                    new Uri(string.Format("https://{0}/", key))).Count > 0)
                {
                    Console.WriteLine(cookieJar.Count+" HTTPS COOKIES FOUND:");
                    Console.WriteLine("----------------------------------");
                    foreach (Cookie cookie in cookieJar.GetCookies(
                        new Uri(string.Format("https://{0}/", key))))
                    {
                        Console.WriteLine(
                            "Name = {0} ; Value = {1} ; Domain = {2}", 
                            cookie.Name, cookie.Value,cookie.Domain);
                    }
                }
            }
        }
        catch(Exception e)
        {
            Console.WriteLine (e);
        }
    }

答案 4 :(得分:1)

如果您要编写nUnit测试,它将是这样的:

    [Test]
    public void Test()
    {

        CookieContainer cookies = new CookieContainer();
        cookies.Add(new Cookie("name1", "value1", "/", "www.domain1.com"));
        cookies.Add(new Cookie("name2", "value2", "/", "www.domain2.com"));

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



        foreach (var key in table.Keys)
        {
            foreach (Cookie cookie in cookies.GetCookies(new Uri(string.Format("http://{0}/", key.ToString().Substring(1,key.ToString().Length - 1)))))
            {
                Assert.That(cookie != null);
                //Console.WriteLine("Name = {0} ; Value = {1} ; Domain = {2}", cookie.Name, cookie.Value,
                //                  cookie.Domain);
            }
        }



    }

答案 5 :(得分:0)

这是一个扩展程序,它结合了antfx的代码和Adrian Lopez使用http和https的想法。对于可能发现有用的人来说,只需快速解决问题:

public static class CookieContainerExtensions
{
    public static List<Cookie> List(this CookieContainer container)
    {
        var cookies = new List<Cookie>();

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

        foreach (var key in table.Keys)
        {
            var domain = key as string;

            if (domain == null)
                continue;

            if (domain.StartsWith("."))
                domain = domain.Substring(1);

            var httpAddress = string.Format("http://{0}/", domain);
            var httpsAddress = string.Format("https://{0}/", domain);

            if (Uri.TryCreate(httpAddress, UriKind.RelativeOrAbsolute, out var httpUri))
            {
                foreach (Cookie cookie in container.GetCookies(httpUri))
                {
                    cookies.Add(cookie);
                }
            }
            if (Uri.TryCreate(httpsAddress, UriKind.RelativeOrAbsolute, out var httpsUri))
            {
                foreach (Cookie cookie in container.GetCookies(httpsUri))
                {
                    cookies.Add(cookie);
                }
            }
        }

        return cookies;
    }
}