我以前使用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”前缀选择在事事处处。

scroll top