Question

Je l'ai déjà utilisé un CookieContainer avec des séances HttpWebRequest et HttpWebResponse, mais maintenant, je veux l'utiliser avec un WebClient. Pour autant que je comprends, il n'y a pas de méthode intégrée comme il est pour HttpWebRequests (request.CookieContainer). Comment puis-je récupérer les cookies d'un WebClient dans un CookieContainer?

Je googlé pour cela et trouvé l'exemple suivant :

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

Est-ce la meilleure façon de le faire?

Était-ce utile?

La solution

Oui. À mon humble avis, remplaçant GetWebRequest () est la meilleure solution pour functionalty limitée de WebClient. Avant que je connaissais cette option, je l'ai écrit beaucoup de code très douloureux à la couche HttpWebRequest parce WebClient presque, mais pas tout à fait, a fait ce que je avais besoin. Dérivation est beaucoup plus facile.

Une autre option consiste à utiliser la classe régulière WebClient, mais remplir manuellement l'en-tête de Cookie avant de faire la demande puis retirez l'en-tête Set-témoins sur la réponse. Il existe des méthodes auxiliaires sur la classe CookieContainer qui rendent la création et l'analyse de ces en-têtes plus facile: CookieContainer.SetCookies() et href="http://msdn.microsoft.com/en-us/library/system.net.cookiecontainer.getcookieheader.aspx" rel="noreferrer"> CookieContainer.GetCookieHeader() , respectivement.

Je préfère l'ancienne approche, car il est plus facile pour l'appelant et nécessite un code moins répétitif que la seconde option. En outre, l'approche de dérivation fonctionne de la même manière pour plusieurs scénarios d'extensibilité (par exemple les cookies, les procurations, etc.).

Autres conseils

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

Commentaires

Comment formater le nom et la valeur du cookie en place de « somecookie »?

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

Pour plusieurs cookies:

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

Celui-ci est tout simplement l'extension de l'article que vous avez trouvé.


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

Le HttpWebRequest modifie le CookieContainer qui lui est attribué. Il n'y a pas besoin de traiter les cookies retournés. Il suffit d'attribuer votre conteneur de cookie à chaque demande 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;
    }
}

Je pense qu'il ya plus propre chemin où vous ne devez pas créer une nouvelle webclient (et ça va travailler avec les bibliothèques 3ème partie ainsi)

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

Maintenant, tout ce que vous devez faire est opt-in pour lequel vous souhaitez utiliser domaines ceci:

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

Cela signifie TOUT WebRequest qui va à example.com va maintenant utiliser votre commande WebRequest créateur, y compris le webclient standard. Cette approche signifie que vous ne touchez pas à tout ce que vous code. Vous appelez simplement le préfixe de registre une fois et être fait avec elle. Vous pouvez également vous inscrire pour le préfixe « http » d'opter pour tout partout.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top