Frage

Ich habe zuvor einen CookieContainer mit httpwebRequest- und httpwebresponse -Sitzungen verwendet, aber jetzt möchte ich ihn mit einem Webclient verwenden. Soweit ich weiß, gibt es keine integrierte Methode wie für httpwebRequests ((request.CookieContainer). Wie kann ich Kekse von einem Webclient in einem CookieContainer sammeln?

ich Googled dafür und gefunden die folgende Probe:

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

Ist das der beste Weg, dies zu tun?

War es hilfreich?

Lösung

Ja. IMHO, übergeordnetes GetWebRequest () ist die beste Lösung für die begrenzte Funktionalität von WebClient. Bevor ich von dieser Option wusste, schrieb ich viele wirklich schmerzhafte Code auf der HTTPWebRequest -Ebene, weil WebClient fast, aber nicht ganz, das tat, was ich brauchte. Die Ableitung ist viel einfacher.

Eine andere Möglichkeit besteht darin, die reguläre Webclient-Klasse zu verwenden, aber den Cookie-Header manuell zu füllen, bevor Sie die Anfrage stellen, und dann den Set-Cookies-Header bei der Antwort herausziehen. Es gibt Helfermethoden in der CookieContainer -Klasse, die das Erstellen und Parsen dieser Header erleichtern: CookieContainer.SetCookies() und CookieContainer.GetCookieHeader(), beziehungsweise.

Ich bevorzuge den ersteren Ansatz, da er für den Anrufer einfacher ist und weniger wiederholte Code als die zweite Option benötigt. Außerdem funktioniert der Ableitungsansatz für mehrere Erweiterbarkeitsszenarien (z. B. Cookies, Proxies usw.).

Andere Tipps

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

Aus Kommentaren

Wie format man den Namen und den Wert des Keks anstelle von "Somecookie"?

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

Für mehrere Kekse:

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

Dieser ist nur Erweiterung des Artikel, den Sie gefunden haben.


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

Der HTTPWebRequest modifiziert den ihm zugewiesenen CookieContainer. Es ist nicht erforderlich, zurückgegebene Cookies zu verarbeiten. Weisen Sie Ihren Cookie -Container einfach jeder Webanforderung zu.

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

Ich denke, es gibt einen saubereren Weg, bei dem Sie keinen neuen Webclient erstellen müssen (und es wird auch mit Bibliotheken der Drittanbieter funktionieren)

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

Jetzt müssen Sie nur noch die Domänen verwenden, die Sie verwenden möchten:

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

Dies bedeutet, dass jeder WebRequest, der zu example.com geht, jetzt Ihren benutzerdefinierten WebRequest -Ersteller, einschließlich des Standard -Webclient, verwendet. Dieser Ansatz bedeutet, dass Sie nicht alle Code berühren müssen. Sie rufen einfach das Registerpräfix einmal an und werden damit fertig. Sie können sich auch für das Präfix "HTTP" registrieren, um sich überall für alles zu entscheiden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top