无法使用WebClient接收cookie

本文关键字:接收 cookie WebClient | 更新日期: 2023-09-27 18:14:39

如果我想错了请指正。

据我所知,WebClient类的任何新实例都会启动一个新的会话,生成新的会话id。

为了防止这种情况,我应该从第一次使用中接收一个会话id,然后将它传递给所有新的WebClients实例。(对于"GET"方法,可以作为任何其他参数添加到请求中)

理论上,可以这样做,使用class:

public class ExtendedWebClient : WebClient
{
    public CookieContainer CookieContainer { get; private set; }
    [SecuritySafeCritical]
    public ExtendedWebClient()
    {
        this.CookieContainer = new CookieContainer();
    }
    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
            (request as HttpWebRequest).CookieContainer = this.CookieContainer;
        return request;
    }
}

但是这并不适用于jsessionid cookie,这种方法有两个问题。

  1. 我无法在保存的CookieContainer中看到jsessionid值。
  2. 即使我将使用不同的方法接收该值,如下面的方法,然后将该值添加到请求uri &jsessionid=someValue,这也无济于事。

我已经检查了几次,任何时候我在Windows Phone中发送这样的请求,响应有一个不同的和唯一的jsessionid。

但是,如果我在浏览器中编写这样的请求,则响应返回正确的jsessionid。


下面的代码允许从Windows Phone的响应中接收jsessionid值(使用HttpWebRequest而不是WebClient),但不能解决问题:

                        // working with some uri
                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                        request.Method = "GET";
                        request.CookieContainer = new CookieContainer();
                        request.BeginGetResponse(asynchronousResult =>
                            {
                                try
                                {
                                    using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult))
                                    {
                                        CookieCollection cookies = response.Cookies;
                                        foreach (Cookie c in cookies)
                                        {
                                            if (c.Name == "JSESSIONID")
                                                // jsessionid value is here. Can be saved & stored somewhere
                                        }
                                        response.Close();
                                    }

                                catch (Exception e)
                                {
                                    // handling exception somehow
                                }
                            }
                        , request);

无法使用WebClient接收cookie

正确,所以如果jsessionid值可以使用问题中提供的方式接收,那么解决方案将是使用HttpWebRequest作为ExtendedWebClient以某种方式忽略jsession值。

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.CookieContainer = new CookieContainer();
            request.CookieContainer.Add(new Uri(url, UriKind.Absolute), StoredCookieCollection._CookieCollection);
            request.BeginGetResponse(new AsyncCallback(GetSomething), request);
           private void GetSomething(IAsyncResult asynchronousResult)
           {
              // do something
           }
           // where in url a jsession value is added to the request as &jsessionid=value

另一件事,在Windows Phone中也不能工作的是,你不能很容易地序列化CookieCollection类型值。因此,我决定在IsolatedStorage设置中存储字符串类型的JSESSIONID值,而不是它,并创建一个静态类StoredCookieCollection,这将在应用程序工作期间存储CookieCollection。

因此,当您接收到jsessionid值时,它作为字符串保存在设置中,并作为CookieCollection保存在静态类中:

using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult))
                                    {
                                        CookieCollection cookies = response.Cookies;
                                        StoredCookieCollection._CookieCollection = cookies;
                                        ...
                                    }

这种方法将真正迫使应用程序在单个会话中工作。

也许CookieCollection序列化有一个更优雅的解决方案,但是我找不到