使用的CookieContainer使用WebClient类
-
21-09-2019 - |
题
我以前使用HttpWebRequest和HttpWebResponse会话中的CookieContainer,但现在,我想与一个Web客户端使用。据我了解,没有内置的方法好像有用于HttpWebRequests(request.CookieContainer
)。 如何可以我收集的Cookie中的CookieContainer一个Web客户端?
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()是Web客户端的有限functionalty的最佳解决方案。之前,我知道这个选项,我在HttpWebRequest的层编写了许多真的很痛代码,因为WebClient的差不多,但不完全,做了我需要的东西。推导要容易得多。
另一种选择是使用常规的WebClient类,但手动发出请求之前填充Cookie头部,然后拉出的Set-饼干头上的响应。有对的CookieContainer类的辅助方法,它使创建和解析这些头容易:的 CookieContainer.SetCookies()
和 CookieContainer.GetCookieHeader()
一>分别。
我更喜欢前一种方法,因为它是为调用者更容易,需要比第二个选项少重复的代码。另外,推导的方法相同的方式工作为多个扩展性方案(例如饼干,代理服务器,等等)。
其他提示
WebClient wb = new WebClient();
wb.Headers.Add(HttpRequestHeader.Cookie, "somecookie");
发件人评论强>
如何格式化cookie的名称和值来代替“somecookie”?
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。只要你的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;
}
}
我觉得有更清洁的方式,你不必创建一个新的Web客户端(它会与第三方库以及工作)
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);
这是指任何WebRequest的是去example.com现在将使用自定义的WebRequest创作者,包括标准的Web客户端。这种方法意味着你没有碰你的代码。你只需要调用一次寄存器前缀和用它做。 您也可以注册“HTTP”前缀选择在事事处处。