开发者

Displaying cookies as key=value for all domains?

This question pertains to the use of the cookie-capable WebClient derived class presented in the How can I get the WebClient to use Cookies? question.

I'd like to use a ListBox to...

1) display each cookie individually as "key=value" (the For Each loop displays all of them as one string), and

2) be able to display all cookies, regardless of the domain from which they came ("www.google.com", here):

Imports System.IO
Imports System.Net

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim webClient As New CookieAwareWebClient
        Const URL = "http://www.google.com"
        Dim response As String

        response = webClient.DownloadString(URL)
        RichTextBox1.Text = response

        'How to display cookies as key/value in ListBox?
        'PREF=ID=5e770c1a9f279d5f:TM=1274032511:LM=1274032511:S=1RDPaKJKpoMT9T54
        For Each mycc In webClient.cc.GetCookies(New Uri(URL))
            ListBox1.Items.Add(mycc.ToString)
        Next
    End Sub
End Class

Public Class CookieAwareWebClient
    Inherits WebClient

    Public cc As New CookieContainer()
    Private lastPage As String

    Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
        Dim R = MyBase.GetWebRequest(address)
        If TypeOf R Is HttpWebRequest Then
            With DirectCast(R, HttpWebRequest)
                .CookieContainer = cc
                If Not lastPage Is Nothing Then
                    .Referer = lastPage
                End If
            End With
        End If
        lastPage = address.ToString()
        Return R
    End Function
End Class

Thank you.


Edit: With the code below, I still get a single-line key=value instead of the individual key=value pairs I need to display:

'How to display cookies as key=value in ListBox?
'still displayed as key=PREF value=ID=c1c024db87787437:TM=1274083167:LM=1274083167:S=ZsG7BXqbCe7yVgJY
Dim mycookiecollection As CookieCollection
mycookiecollection = webClient.cc.GetCookies(New Uri(URL))
Dim mycookie As Cookie
For Each mycookie In mycookiecollection
    ListBox1.Items.Add(mycookie.Name & vbTab & mycookie.Value)
    'MessageBox.Show(mycookie.Name & vbTab & mycookie.Value)
Next

Edit: Turns out Google returned a single cookie with key=PREF, and value=a concatenation of multiple key=value items.

For those interested, here's some code to parse through the value part:

For Each ck As Cookie In cookies
    Dim ht As New Web.HttpCookie(ck.Name, ck.Value.Replace(":开发者_运维技巧", "&"))
    If ht.HasKeys Then
        Debug.WriteLine(ht.Name)
        For Each key In ht.Values.AllKeys
            Debug.WriteLine(vbTab & key & vbTab & ht.Values(key))
        Next
    Else
        Debug.WriteLine(ht.Name & vbTab & ht.Value)
    End If
Next


CookieContainer cookies = new CookieContainer();

// do something to get some cookies

Hashtable domains= 
    (Hashtable) typeof (CookieContainer)
    .GetField("m_domainTable", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(cookies);

foreach (DictionaryEntry domain in domains)
{
    CookieCollection domainCookies = cookies.GetCookies(new Uri("http://" + domain.Key));

    foreach (Cookie cookie in domainCookies)
    {
        Console.WriteLine("Domain:{0}, Path:{1}, Port:{2}, Name:{3}, Value:{4}", cookie.Domain, cookie.Path, cookie.Port, cookie.Name, cookie.Value);
    }

}


The Cookie class has Name and Value properties that you can use, instead of calling ToString() which only produces a string suitable to use in an HTTP header.

There is no way to enumerate the domains that the cookie container has cookies for, so you would have to keep a list of domains also, so that you can use GetCookies to get the cookies for each of the domains.


The CookieContainer object has a GetCookies method that returns a CookieCollection.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜