質問

私は以前、httpwebrequestとhttpwebresponseセッションを備えたCookieContainerを使用しましたが、今ではWebClientで使用したいと思います。私が理解している限り、httpwebrequestsのような組み込み方法はありません(request.CookieContainer). CookieContainerのWebClientからCookieを収集するにはどうすればよいですか?

グーグルでグーグル これと見つけた 次のサンプル:

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

これはそれをするための最良の方法ですか?

役に立ちましたか?

解決

はい。 Imho、Overriding getWebRequest()は、WebClientの限られた機能性の最良のソリューションです。このオプションを知る前に、WebClientがほとんど、しかしまったく必要なことをしたことがあるため、HTTPWEBREQUESTレイヤーに非常に痛みを伴うコードをたくさん書きました。派生ははるかに簡単です。

別のオプションは、通常のWebClientクラスを使用することですが、リクエストを行う前にCookieヘッダーを手動で入力してから、応答でセットクーキーヘッダーを引き出します。 CookieContainerクラスには、これらのヘッダーの作成と解析を簡単にするヘルパーメソッドがあります。 CookieContainer.SetCookies()CookieContainer.GetCookieHeader(), 、 それぞれ。

発信者にとっては簡単で、2番目のオプションよりも繰り返しコードが少ないため、以前のアプローチを好みます。また、派生アプローチは、複数の拡張性シナリオ(Cookie、Proxiesなど)で同じように機能します。

他のヒント

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

コメントから

「SomeCookie」の代わりにCookieの名前と価値をどのようにフォーマットしますか?

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

複数のクッキーの場合:

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

これはあなたが見つけた記事の単なる拡張です。


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

HTTPWEBREQUESTは、割り当てられたCookIeContainerを変更します。返されたCookieを処理する必要はありません。すべてのWebリクエストにCookieコンテナを割り当てるだけです。

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

新しいWebClientを作成する必要がない場合は、よりクリーンな方法があると思います(そして、サードパーティのライブラリでも動作します)

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

これで、これを使用するドメインを選択するだけです。

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

つまり、example.comに進むWebRequestは、標準のWebClientを含むカスタムWebRequest Creatorを使用するようになりました。このアプローチは、コードをすべて触れる必要がないことを意味します。レジスタのプレフィックスを一度呼び出して、それで完了します。 「HTTP」プレフィックスに登録して、どこでもすべてをオプトインすることもできます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top