Pregunta

He utilizado previamente un CookieContainer con HttpWebRequest y HttpWebResponse sesiones, pero ahora, quiero usarlo con un cliente Web. Por lo que yo entiendo, no hay ningún método integrado como lo hay para HttpWebRequests (request.CookieContainer). ¿Cómo puedo recoger las cookies de un cliente Web en un CookieContainer?

en Google para esto y encontré el siguiente ejemplo de :

public class CookieAwareWebClient : WebClient
{
    private readonly CookieContainer m_container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        HttpWebRequest webRequest = request as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.CookieContainer = m_container;
        }
        return request;
    }
}

Es ésta la mejor manera de hacerlo?

¿Fue útil?

Solución

Sí. En mi humilde opinión, anulando GetWebRequest () es la mejor solución para functionalty limitada del cliente Web. Antes de saber acerca de esta opción, escribí un montón de código muy doloroso en la capa de cliente Web HttpWebRequest porque casi, pero no del todo, hizo lo que necesitaba. La derivación es mucho más fácil.

Otra opción es utilizar la clase WebClient regular, pero rellenar manualmente la cabecera Cookie antes de hacer la solicitud y luego tire de la cabecera Set-cookies en la respuesta. Hay métodos de ayuda en la clase CookieContainer que hacen que la creación y análisis de estas cabeceras más fácil: CookieContainer.SetCookies() y href="http://msdn.microsoft.com/en-us/library/system.net.cookiecontainer.getcookieheader.aspx" rel="noreferrer"> CookieContainer.GetCookieHeader() , respectivamente.

Yo prefiero el primer enfoque, ya que es más fácil para la persona que llama y requiere menos código repetitivo que la segunda opción. Además, el enfoque de derivación funciona del mismo modo para múltiples escenarios de extensibilidad (por ejemplo, las galletas, los proxies, etc.).

Otros consejos

 WebClient wb = new WebClient();
 wb.Headers.Add(HttpRequestHeader.Cookie, "somecookie");

De Comentarios

¿Cómo se formatea el nombre y el valor de la cookie en lugar de "somecookie"?

wb.Headers.Add(HttpRequestHeader.Cookie, "cookiename=cookievalue"); 

En varias cookies:

wb.Headers.Add(HttpRequestHeader.Cookie, 
              "cookiename1=cookievalue1;" +
              "cookiename2=cookievalue2");

Éste es sólo la extensión del artículo que has encontrado.


public class WebClientEx : WebClient
{
    public WebClientEx(CookieContainer container)
    {
        this.container = container;
    }

    public CookieContainer CookieContainer
        {
            get { return container; }
            set { container= value; }
        }

    private CookieContainer container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest r = base.GetWebRequest(address);
        var request = r as HttpWebRequest;
        if (request != null)
        {
            request.CookieContainer = container;
        }
        return r;
    }

    protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
    {
        WebResponse response = base.GetWebResponse(request, result);
        ReadCookies(response);
        return response;
    }

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse response = base.GetWebResponse(request);
        ReadCookies(response);
        return response;
    }

    private void ReadCookies(WebResponse r)
    {
        var response = r as HttpWebResponse;
        if (response != null)
        {
            CookieCollection cookies = response.Cookies;
            container.Add(cookies);
        }
    }
}

El HttpWebRequest modifica el CookieContainer asignado. No hay necesidad de procesar las galletas devueltos. Simplemente asigne su contenedor de galletas para cada solicitud Web.

public class CookieAwareWebClient : WebClient
{
    public CookieContainer CookieContainer { get; set; } = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri uri)
    {
        WebRequest request = base.GetWebRequest(uri);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = CookieContainer;
        }
        return request;
    }
}

Creo que hay manera más limpia en la que no tiene que crear una nueva webclient (y que va a trabajar con bibliotecas 3 ª parte también)

internal static class MyWebRequestCreator
{
    private static IWebRequestCreate myCreator;

    public static IWebRequestCreate MyHttp
    {
        get
        {
            if (myCreator == null)
            {
                myCreator = new MyHttpRequestCreator();
            }
            return myCreator;
        }
    }

    private class MyHttpRequestCreator : IWebRequestCreate
    {
        public WebRequest Create(Uri uri)
        {
            var req = System.Net.WebRequest.CreateHttp(uri);
            req.CookieContainer = new CookieContainer();
            return req;
        }
    }
}

Ahora todo lo que tiene que hacer es optar por la cual los dominios que desea utilizar esto:

    WebRequest.RegisterPrefix("http://example.com/", MyWebRequestCreator.MyHttp);

Eso significa que cualquier WebRequest que va a example.com utilizará ahora su costumbre WebRequest creador, incluyendo el webclient estándar. Este enfoque significa que usted no tiene que tocar todo lo que código. Que acaba de llamar el prefijo de registro una vez y acabar de una vez. También puede registrarse para prefijo "http" a optar por todo en todas partes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top