How to get cookies info inside of a CookieContainer? (All Of Them, Not For A Specific Domain)

后端 未结 6 1554
野性不改
野性不改 2020-12-09 09:48

Please see the code below:

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


        
相关标签:
6条回答
  • 2020-12-09 10:25

    Improved version of PaRiMal RaJ's code. This method will print both, http and https cookies. Ready to paste it in your class.

        // 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);
            }
        }
    
    0 讨论(0)
  • 2020-12-09 10:27

    None of the answers worked for me. This is my humble solution for the problem.

    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;
    }           
    
    0 讨论(0)
  • 2020-12-09 10:30

    If you were to write a nUnit test, it would be something like this:

        [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);
                }
            }
    
    
    
        }
    
    0 讨论(0)
  • 2020-12-09 10:41

    Thank's to AppDeveloper for their answer, here is a slightly modified version as an extension method.

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

    To get the list just call List() on the CookieContainer:

    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();
    
    0 讨论(0)
  • 2020-12-09 10:42

    Here's an Extension that combines antfx's code with Adrian Lopez's idea of using both http and https. Just a quick fix for anyone who might find it useful:

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-09 10:45

    reflection can be used to get the private field that holds all the domain key in CookieContainer object,

    Q. How do i got the name of that private field ?

    Ans. Using Reflector;

    its is declared as :

    private Hashtable m_domainTable;
    

    once we get the private field, we will get the the domain key, then getting cookies is a simple iteration.

    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)
                {
                    Uri uri = new Uri(string.Format("http://{0}/", key));
    
                    foreach (Cookie cookie in cookies.GetCookies(uri))
                    {
                        Console.WriteLine("Name = {0} ; Value = {1} ; Domain = {2}",
                            cookie.Name, cookie.Value, cookie.Domain);
                    }
                }
    
                Console.Read();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题