이전에는 HttpWebRequest 및 HttpWebResponse 세션과 함께 CookieContainer를 사용했지만 이제는 WebClient와 함께 사용하고 싶습니다. 내가 이해하는 한 HttpWebRequests ( request.CookieContainer
) 와 같은 내장 메소드는 없습니다 . CookieContainer의 WebClient에서 쿠키를 수집하려면 어떻게해야합니까?
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는 GetWebRequest ()를 재정의하는 것이 WebClient의 제한된 기능에 대한 최상의 솔루션입니다. 이 옵션에 대해 알기 전에 HttpWebRequest 레이어에서 WebClient가 거의 고통스럽지 않은 코드를 많이 작성했습니다. 파생이 훨씬 쉽습니다.
또 다른 옵션은 일반 WebClient 클래스를 사용하지만 요청하기 전에 Cookie 헤더를 수동으로 채우고 응답에서 Set-Cookies 헤더를 가져 오는 것입니다. : 만들고 이러한 헤더 쉽게 분석 내린 CookieContainer 클래스의 도우미 방법이 있습니다 CookieContainer.SetCookies()
와 CookieContainer.GetCookieHeader()
각각은,.
나는 호출자가 더 쉽고 두 번째 옵션보다 덜 반복적 인 코드를 필요로하기 때문에 전자의 접근 방식을 선호합니다. 또한 파생 접근 방식은 여러 확장 성 시나리오 (예 : 쿠키, 프록시 등)에 대해 동일한 방식으로 작동합니다.
답변
WebClient wb = new WebClient();
wb.Headers.Add(HttpRequestHeader.Cookie, "somecookie");
댓글에서
“somecookie”대신 쿠키의 이름과 값을 어떻게 포맷합니까?
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를 수정합니다. 반환 된 쿠키를 처리 할 필요가 없습니다. 쿠키 컨테이너를 모든 웹 요청에 할당하기 만하면됩니다.
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으로 이동하는 모든 웹 요청은 이제 표준 웹 클라이언트를 포함하여 사용자 정의 웹 요청 작성자를 사용합니다. 이 접근 방식은 코드를 모두 만질 필요가 없음을 의미합니다. 레지스터 접두사를 한 번만 호출하면됩니다. “http”접두사를 등록하여 모든 곳에서 모든 것을 선택할 수 있습니다.