以前にHttpWebRequestおよびHttpWebResponseセッションでCookieContainerを使用しましたが、今ではWebClientで使用したいです。私の知る限り、HttpWebRequests(request.CookieContainer
)のような組み込みメソッドはありません。 CookieContainerでWebClientからCookieを収集するにはどうすればよいですか?
I googled このために見つかりました 次のサンプル :
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;
}
}
これが最善の方法ですか?
はい。私見、GetWebRequest()をオーバーライドすることは、WebClientの限られた機能に対する最良のソリューションです。このオプションを知る前に、HttpClientRequestレイヤーで非常に苦痛なコードをたくさん書きました。WebClientが必要なことをほぼ完全に行ったからです。導出ははるかに簡単です。
別のオプションは、通常のWebClientクラスを使用しますが、リクエストを行う前にCookieヘッダーを手動で入力してから、応答のSet-Cookiesヘッダーを引き出します。 CookieContainerクラスには、これらのヘッダーの作成と解析を容易にするヘルパーメソッドがあります。それぞれ CookieContainer.SetCookies()
および CookieContainer.GetCookieHeader()
です。
前者のアプローチは、呼び出し元にとって簡単であり、2番目のオプションよりも反復コードが少ないため、好まれます。また、派生アプローチは、複数の拡張性シナリオ(Cookie、プロキシなど)でも同じように機能します。
WebClient wb = new WebClient();
wb.Headers.Add(HttpRequestHeader.Cookie, "somecookie");
コメントから
「somecookie」の代わりにcookieの名前と値をどのようにフォーマットしますか?
wb.Headers.Add(HttpRequestHeader.Cookie, "cookiename=cookievalue");
複数のCookieの場合:
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リクエストに割り当てるだけです。
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;
}
}
新しいウェブクライアントを作成する必要がないクリーンな方法があると思います(そしてサードパーティのライブラリでも動作します)
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作成者を使用するようになります。このアプローチは、コーディングするすべてに触れる必要がないことを意味します。 registerプレフィックスを1回呼び出すだけで済みます。 「http」プレフィックスを登録して、あらゆる場所でオプトインすることもできます。