2012-06-22 13 views
20

estoy tratando de probar la unidad algo de código, y tengo que sustituir este:¿Cómo agregar cookies a WebRequest?

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

con

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

Básicamente, ¿cómo consigo las cookies en la solicitud sin necesidad de utilizar un HttpWebRequest?

+0

Eso sería difícil, ya que las cookies son un concepto HTTP. ¿Hay alguna razón por la que necesites hacer este cambio? – dlev

+0

@dlev - WebRequest creará una HttpWebRequest basada en el uri. Por lo tanto, si quiero simular mi propio objeto WebRequest y/o registrar mi propio uri que también devuelve una WebRequest, no quiero restringir el método para que solo funcione con un objeto HttpWebRequest. –

+1

Entiendo que el tipo de ejecución de 'webRequest' será' HttpWebRequest'. Pero el acceso a 'CookieContainer' requiere que el tipo de tiempo de compilación sea' HttpWebRequest'. Además, menciona no restringirse a HTTP, pero en ese caso, las cookies no significan mucho, ya que son una construcción HTTP (que es la razón de su ausencia en 'WebRequest' en primer lugar.) – dlev

Respuesta

22

Basado en su comentario, es posible que no escribe una 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; 
} 

Entonces usted puede tener un código como:

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

Este código devuelve: "El parámetro '{0}' no puede ser una cadena vacía." en línea httpRequest.CookieContainer.Add (cookie) ;. ¿Alguna idea? –

+2

@drdigit Eso se debe a que no creó una cookie que incluyera un dominio. Además, estoy bastante seguro de que la cadena de error es un error en el BCL (que, lamentablemente, parece haber persistido en 4.5) – dlev

+0

Muchas gracias por la respuesta detallada. –

3

intento con algo como esto:

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

La pregunta no es acerca de la configuración de cookies para la respuesta.Se trata de crear una nueva WebRequest y establecer una cookie para esta solicitud (y observar las etiquetas de la pregunta, ejecutar la solicitud desde la prueba de la unidad). –

+2

esto lanzará un error 'Referencia de objeto no establecida en ...'. Primero, podemos necesitar 'request.CookieContainer = new CookieContainer();' luego el método de llamada de llamada debería funcionar. – shashwat

6

WebRequest es una clase abstracta que no tiene una propiedad CookieContainer. Además, no puede usar la colección Headers (excepción no implementada) por lo que cualquier intento como webRequest.Headers.Add ("Cookie", "...") fallará.

Lo sentimos, pero no tiene posibilidad de utilizar cookies con WebRequest.

Stick on HttpWebRequest y agregue/edite la cantidad de cookies que desee utilizando su colección Headers.

+0

Eso es a lo que le tenía miedo. –

+0

No lo hice :) Su requisito "if then addcookies" puede ser cubierto por HttpWebRequest.Headers.Add ("Cookie", "..."). –

0

La respuesta de dlev terminó funcionando, pero tuve problemas para implementar la solución ("El parámetro '{0}' no puede ser una cadena vacía."), Así que decidí escribir el código completo en caso de que alguien más tenga problemas similares .

Mi objetivo era obtener el html como una cadena, pero necesitaba agregar las cookies a la solicitud web. Esta es la función que descarga la cadena usando las galletas:

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

Estamos utilizando el código de la respuesta de 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; 
} 

Así es como se utiliza el código completo:

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