views:

102

answers:

3

Hello,

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
A: 

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.

Guffa
Thanks for the into, but the derived class CookieAwareWebClient above uses the a CookieContainer(), which doesn't have Name/Value properties. Is it possible to turn a CookieContainer into a Cookie, or somehow extract infos from a CookieContainer?
OverTheRainbow
A: 
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);
    }

}
Sky Sanders
Thanks but I'm still getting "key=PREF value=ID=c1c024db87787437:TM=1274083167:LM=1274083167:S=ZsG7BXqbCe7yVgJY" instead of ID=123, LM=12345, etc.
OverTheRainbow
@Over - I understand, the code is an example of how to get the cookies out of a CookieContainer. Unfortunately, unlike `System.Web.HttpCookie`, `System.Net.Cookie` does not have an indexer or keys. You will need to use a regex to parse your cookie value. If the cookies are well formed then a simple regex will suffice.
Sky Sanders
Thanks. If there's no better way, I'll regex through the one-line cookie.
OverTheRainbow
A: 

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

Chris Haas