2012-12-02 4 views
10

아래 코드를 참조하십시오 (안 특정 도메인의 경우 모두) :쿠키 정보를 CookieContainer 내부에서 가져 오는 방법은 무엇입니까?

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 내부 쿠키 정보를 얻을 수 있습니까? (모두 특정 도메인에만 국한되지 않음)
쿠키를 어떻게 추가하거나 제거 할 수 있습니까?

답변

13

반사, CookieContainer 개체의 모든 도메인 키를 보유하고있는 개인 필드를 가져올 수 있습니다 내가 그 개인 필드의 이름을 가지고 어떻게

Q.?

Ans. 리플렉터 사용하기.

그것으로 선언한다 : 우리는 개인 필드를 일단

private Hashtable m_domainTable; 

, 우리는 도메인 키를 얻을 것이다, 다음 쿠키를 얻는 것은 단순 반복이다. 당신이 NUnit과 테스트를 작성한다면

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

    } 

} 
+0

이 방법은 http 프로토콜을 사용하는 것으로 보이며 https 용으로 생성 된 쿠키는 표시되지 않습니다. – user1713059

+0

@ user1713059 - HTTP에서만이 작업을 수행하고 있음을 보여주는 위치는 어디입니까? 어쨌든 이 경우 http + https에 대한 쿠키가 생성됩니다. –

+0

콘솔 출력 루프에는'string.Format ("http : //')가 있습니다 .GetCookies 메소드는 http로 시작하는 도메인 이름을 사용하여 호출됩니다 – user1713059

1

, 그것은이 같은 것입니다 :

[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

도메인과 두 번째 foreach statement. –

5

감사의 자신의 대답을 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에) 목록 (전화 목록을 얻으려면 : PaRiMal 주권의 코드

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

foreach 루프 외부의 메서드에 return 문을 넣을 수 있습니다. – PixelZerg

3

향상된 버전입니다. 그러면 http와 https 쿠키가 모두 인쇄됩니다. 수업에 붙여 넣을 준비가되었습니다.

// 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); 
     } 
    } 
+1

코드 작동하지만, 가끔 UriFormatException 오류가 발생합니다. 이러한 쿠키를 인쇄하는 방법에 대한 제안이 있습니까? –

관련 문제