2012-06-22 10 views
20

Sto cercando di unit test del codice, e ho bisogno di sostituire questo:Come aggiungere cookie a WebRequest?

HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri); 
    httpWebRequest.CookieContainer = new CookieContainer(); 

con

WebRequest webRequest = WebRequest.Create(uri); 
    webRequest.CookieContainer = new CookieContainer(); 

In sostanza, come faccio a ottenere i cookie nella richiesta senza utilizzare un HttpWebRequest?

+0

Sarebbe difficile, dato che i cookie sono un concetto HTTP. C'è una ragione per cui devi apportare questo cambiamento? – dlev

+0

@dlev - WebRequest creerà un HttpWebRequest basato su uri. Quindi, se voglio prendere in giro la mia propria WebRequest oggetto e/o registrare il mio URI che restituisce anche un WebRequest, allora io non voglio per vincolare il metodo per lavorare solo con un oggetto HttpWebRequest. –

+1

Capisco che il tipo run-time di 'webRequest' sarà' HttpWebRequest'. Ma l'accesso a 'CookieContainer' richiede che il tipo in fase di compilazione sia' HttpWebRequest'. Inoltre, non parlare di te stesso vincolante per HTTP, ma in quel caso, i cookie non significa molto, dal momento che sono un costrutto HTTP – dlev

risposta

22

sulla base di osservazioni, si potrebbe considerare la scrittura di un extension method:

public static bool TryAddCookie(this WebRequest webRequest, Cookie cookie) 
{ 
    HttpWebRequest httpRequest = webRequest as HttpWebRequest; 
    if (httpRequest == null) 
    { 
     return false; 
    } 

    if (httpRequest.CookieContainer == null) 
    { 
     httpRequest.CookieContainer = new CookieContainer(); 
    } 

    httpRequest.CookieContainer.Add(cookie); 
    return true; 
} 

Quindi è possibile avere il codice come:

WebRequest webRequest = WebRequest.Create(uri); 
webRequest.TryAddCookie(new Cookie("someName","someValue")); 
+1

Questo codice restituisce: "Il parametro '{0}' non può essere una stringa vuota." on line httpRequest.CookieContainer.Add (cookie) ;. Qualche idea? –

+2

@drdigit Questo perché non hai creato un cookie che includeva un dominio. Inoltre, sono abbastanza sicuro che la stringa di errore sia un bug nel BCL (che, sfortunatamente, sembra essere persistito in 4.5) – dlev

+0

Grazie mille per la risposta dettagliata. –

3

prova con qualcosa di simile:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/default.html"); 
request.CookieContainer.Add(new Cookie("ConstoCookie", "Chocolate Flavour")); 
+0

La questione non è su come impostare dei cookie alla risposta.Riguarda la creazione di nuovi WebRequest e l'impostazione di un cookie per questa richiesta (e guardando i tag della domanda, eseguendo la richiesta dal test dell'unità). –

+2

questo genererà un errore 'Riferimento oggetto non impostato su un ...'. Per prima cosa potremmo aver bisogno di 'request.CookieContainer = new CookieContainer();' quindi chiamare Add metodo dovrebbe funzionare. – shashwat

6

WebRequest è una classe astratta che non ha una proprietà CookieContainer. Inoltre, non è possibile utilizzare la raccolta Headers (eccezione non implementata), quindi qualsiasi tentativo come webRequest.Headers.Add ("Cookie", "...") avrà esito negativo.

Ci dispiace, ma non si ha la possibilità di utilizzare i cookie con WebRequest.

Stick sul HttpWebRequest e aggiungere/modificare il maggior numero di biscotti ti piace usare la sua collezione intestazioni!

+0

Questo è quello di cui avevo paura. –

+0

Non l'ho fatto :) Il requisito "if then addcookies" può essere coperto da HttpWebRequest.Headers.Add ("Cookie", "..."). –

0

La risposta di dlev ha funzionato, ma ho avuto problemi nell'implementazione della soluzione ("Il parametro '{0}' non può essere una stringa vuota."), Così ho deciso di scrivere il codice completo nel caso in cui qualcun altro avesse problemi simili .

Il mio obiettivo era quello di ottenere il codice HTML come una stringa, ma avevo bisogno di aggiungere i biscotti alla richiesta web. Questa è la funzione che scarica la stringa utilizzando i cookie:

public static string DownloadString(string url, Encoding encoding, IDictionary<string, string> cookieNameValues) 
{ 
    using (var webClient = new WebClient()) 
    { 
     var uri = new Uri(url); 
     var webRequest = WebRequest.Create(uri); 
     foreach(var nameValue in cookieNameValues) 
     { 
      webRequest.TryAddCookie(new Cookie(nameValue.Key, nameValue.Value, "/", uri.Host)); 
     }     
     var response = webRequest.GetResponse(); 
     var receiveStream = response.GetResponseStream(); 
     var readStream = new StreamReader(receiveStream, encoding); 
     var htmlCode = readStream.ReadToEnd();     
     return htmlCode; 
    } 
} 

Stiamo usando il codice dalla risposta di dlev:

public static bool TryAddCookie(this WebRequest webRequest, Cookie cookie) 
{ 
    HttpWebRequest httpRequest = webRequest as HttpWebRequest; 
    if (httpRequest == null) 
    { 
     return false; 
    } 

    if (httpRequest.CookieContainer == null) 
    { 
     httpRequest.CookieContainer = new CookieContainer(); 
    } 

    httpRequest.CookieContainer.Add(cookie); 
    return true; 
} 

Questo è il modo di utilizzare il codice completo:

var cookieNameValues = new Dictionary<string, string>(); 
cookieNameValues.Add("varName", "varValue"); 
var htmlResult = DownloadString(url, Encoding.UTF8, cookieNameValues); 
Problemi correlati