#windows-phone-7.1 #windows-phone-7 #cookiecontainer
#windows-phone-7.1 #windows-phone-7 #cookiecontainer
Вопрос:
У меня есть производственное приложение, которое выполняет два вызова через HttpWebRequest. Первый вызов устанавливает сеанс и получает файлы cookie обратно для поддержания сеанса, второй вызов предназначен для получения данных из api. Ответы являются httponly. Я использую общий CookieContainer между двумя вызовами, но второй вызов всегда завершается неудачей. Я сузил проблему до файлов cookie, которые не отправляются во втором запросе. Я использовал сетевой монитор для просмотра трафика, и если я явно установлю файлы cookie во втором запросе (см. Код ниже), вызов завершится успешно. У кого-нибудь есть идеи по этому вопросу? Мне нужно выяснить, как заставить его работать с общим CookieContainer.
private string URL_01 = "https:// [...]";
private string URL_02 = "https:// [...]";
private CookieContainer _cookieContainer = new CookieContainer();
private NetworkCredential nc = new NetworkCredential("username", "password");
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
HttpWebRequest request = HttpWebRequest.CreateHttp(URL_01);
request.CookieContainer = _cookieContainer;
request.Credentials = nc;
request.UseDefaultCredentials = false;
request.BeginGetResponse(new AsyncCallback(HandleResponse), request);
}
public void HandleResponse(IAsyncResult result)
{
HttpWebRequest request = result.AsyncState as HttpWebRequest;
if (request != null)
{
using (WebResponse response = request.EndGetResponse(result))
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string data = reader.ReadToEnd();
// gets returned data and deserializes it to an object
SessionObject so = JsonConvert.DeserializeObject<SessionObject>(data);
if (so.DeviceAPI.Session == "true")
{
// make a second call for the data
HttpWebRequest requestData = HttpWebRequest.CreateHttp(URL_02);
// when this is used, the call fails
requestData.CookieContainer = _cookieContainer;
// when this is used, the call works
//requestData.Headers[HttpRequestHeader.Cookie] = "_key=value; _secret=value";
requestData.Credentials = nc;
requestData.BeginGetResponse(new AsyncCallback(DataResponse), requestSongData);
}
}
}
}
}
public void DataResponse(IAsyncResult DataResult)
{
HttpWebRequest requestData = DataResult.AsyncState as HttpWebRequest;
if (requestData != null)
{
using (WebResponse dataResponse = requestData.EndGetResponse(DataResult))
{
using (StreamReader reader = new StreamReader(dataResponse.GetResponseStream()))
{
string data = reader.ReadToEnd();
// do something with the data
}
}
}
}
}
}
Ответ №1:
Эта проблема является известной проблемой с CookieContainer, когда в имени домена нет «www». CookieContainer ожидает «www» и не идентифицирует существующие файлы cookie для домена.
Обходной путь заключался в том, чтобы считывать файлы cookie из заголовков ответов и добавлять их к любым другим запросам.
Рассматривалось исправление для Mango, но было удалено.
Джефф
Комментарии:
1. Приветствия. Возникла та же проблема, и я искал подтверждение поведения от кого-то другого. Теперь я знаю!
Ответ №2:
У меня была его проблема, и, похоже, она была связана с использованием старого контейнера для файлов cookie. Просто создайте новый, выполнив итерацию по старому и создав новые файлы cookie.
Шаг 1. Создайте словарь для хранения файлов cookie.
//create a dictionary to store your persistent cookies
public static Dictionary<string, Cookie> CookieCollection { get; set; }
Шаг 2. Добавьте сохраненные вами файлы cookie в веб-запрос перед его отправкой.
var request = WebRequest.Create(...);
//add the cookies you have in your persistent cookie jar
foreach (KeyValuePair<string, Cookie> cookie in _collection)
{
try
{
request.CookieContainer.Add(request.RequestUri, new Cookie(cookie.Value.Name, cookie.Value.Value));
}
catch
{
}
}
Шаг 3. Сохранение файлов cookie
ResponseCallback(…) {
//update your local cookie list as required
foreach (Cookie clientcookie in response.Cookies)
{
if (!_collection.ContainsKey(clientcookie.Name))
_collection.Add(clientcookie.Name, clientcookie);
else
_collection[clientcookie.Name] = clientcookie;
}
}
Комментарии:
1. Когда я пытаюсь выполнить этот код, я получаю сообщение об ошибке «оператор foreach не может работать с переменными типа’System.Net.CookieContainer’, поскольку ‘System.Net.CookieContainer’ не содержит общедоступного определения для ‘GetEnumerator’. Это тот способ, которым вы смогли его использовать? Спасибо.
2. @JeffParies Извините за это, был вдали от компьютера и не смог проверить в коде. Я обновил ответ.
3. спасибо, я посмотрю, смогу ли я это реализовать … работает ли это с файлами cookie httponly?
4. Нет. Файлы cookie, помеченные HttpOnly, не могут быть сохранены. См. forums.create.msdn.com/forums/p/64708/396364.aspx#396364
5. Эти файлы cookie являются HttpOnly — мне не обязательно их сохранять, но они не сохраняются между вызовами.