2012-12-02 16 views
10

は、以下のコードを参照してください(未特定のドメインのためにそれらのすべて、):CookieContainer内のCookie情報を取得するには?

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を追加または削除できますか?

答えて

13

反射は、CookieContainerオブジェクト内のすべてのドメインキーを保持しているプラ​​イベートフィールドを取得するために使用することができ、私はそのプライベートフィールドの名前を得たどうすればよい

Q.?

Ans。リフレクターを使用する。

そのは次のように宣言されています。私たちはプライベートフィールドを得れば、私たちは、ドメインキーを取得します、そしてクッキーを取得することは、単純な反復である

private Hashtable m_domainTable; 

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の両方のCookieが取得されます。 –

+0

コンソール印刷ループに 'string.Format(" http:// 'があります.' GetCookies'メソッドは、httpだけで始まるドメイン名を使用して呼び出されます。 – user1713059

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



    } 
+0

ドメインと2番目のforeach –

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の両方の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); 
     } 
    } 
+1

コードは正常ですが、UriFormatExceptionエラーが発生することがあります。 –

関連する問題