2013-09-25 9 views

risposta

7

Dalla mia esperienza, ho avuto alcuni problemi con l'utilizzo di HttpWebRequest.CookieContainer per la gestione dei cookie. Può funzionare fino a un certo punto, ma a volte i cookie non sono conformi a RFC e non vengono analizzati correttamente nello CookieContainer. Se gestisci i cookie manualmente aggiungendoli all'intestazione Cookie della richiesta, avrai un successo migliore con determinati siti Web che non sono conformi a RFC. Uno dei problemi con CookieContainer è che se c'è una data con una virgola nella data come "26 settembre 2013", la analizzerà completamente come un cookie separato e interromperà l'analisi. Un altro problema è che i cookie impostati su un reindirizzamento HTTP 302 non verranno raccolti dallo CookieContainer.

Sta a te decidere quale sia il migliore per le tue esigenze specifiche, ma se i problemi con lo CookieContainer forniscono risultati diversi rispetto all'impostazione manuale dell'intestazione del cookie, ti consiglio di limitarti a impostare manualmente l'intestazione del cookie. Speriamo che Microsoft aggiornerà questo in futuro in modo che possiamo tornare a utilizzare le belle classi .NET per la gestione dei cookie.

Edit:
mi sono imbattuto in un codice che analizza correttamente un header "Set-Cookie". Gestisce i cookie separati da virgole e ne estrae il nome, la scadenza, il percorso, il valore e il dominio di ciascun cookie.

Questo codice funziona meglio del parser dei cookie di Microsoft e questo è ciò che dovrebbe fare il parser ufficiale dei cookie. Non ho idea del perché Microsoft non abbia ancora risolto questo problema poiché si tratta di un problema molto comune.

Ecco il codice originale: http://snipplr.com/view/4427/

sto postando qui nel caso in cui il collegamento va giù ad un certo punto:

public static CookieCollection GetAllCookiesFromHeader(string strHeader, string strHost) 
{ 
    ArrayList al = new ArrayList(); 
    CookieCollection cc = new CookieCollection(); 
    if (strHeader != string.Empty) 
    { 
     al = ConvertCookieHeaderToArrayList(strHeader); 
     cc = ConvertCookieArraysToCookieCollection(al, strHost); 
    } 
    return cc; 
} 


private static ArrayList ConvertCookieHeaderToArrayList(string strCookHeader) 
{ 
    strCookHeader = strCookHeader.Replace("\r", ""); 
    strCookHeader = strCookHeader.Replace("\n", ""); 
    string[] strCookTemp = strCookHeader.Split(','); 
    ArrayList al = new ArrayList(); 
    int i = 0; 
    int n = strCookTemp.Length; 
    while (i < n) 
    { 
     if (strCookTemp[i].IndexOf("expires=", StringComparison.OrdinalIgnoreCase) > 0) 
     { 
      al.Add(strCookTemp[i] + "," + strCookTemp[i + 1]); 
      i = i + 1; 
     } 
     else 
     { 
      al.Add(strCookTemp[i]); 
     } 
     i = i + 1; 
    } 
    return al; 
} 


private static CookieCollection ConvertCookieArraysToCookieCollection(ArrayList al, string strHost) 
{ 
    CookieCollection cc = new CookieCollection(); 

    int alcount = al.Count; 
    string strEachCook; 
    string[] strEachCookParts; 
    for (int i = 0; i < alcount; i++) 
    { 
     strEachCook = al[i].ToString(); 
     strEachCookParts = strEachCook.Split(';'); 
     int intEachCookPartsCount = strEachCookParts.Length; 
     string strCNameAndCValue = string.Empty; 
     string strPNameAndPValue = string.Empty; 
     string strDNameAndDValue = string.Empty; 
     string[] NameValuePairTemp; 
     Cookie cookTemp = new Cookie(); 

     for (int j = 0; j < intEachCookPartsCount; j++) 
     { 
      if (j == 0) 
      { 
       strCNameAndCValue = strEachCookParts[j]; 
       if (strCNameAndCValue != string.Empty) 
       { 
        int firstEqual = strCNameAndCValue.IndexOf("="); 
        string firstName = strCNameAndCValue.Substring(0, firstEqual); 
        string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1)); 
        cookTemp.Name = firstName; 
        cookTemp.Value = allValue; 
       } 
       continue; 
      } 
      if (strEachCookParts[j].IndexOf("path", StringComparison.OrdinalIgnoreCase) >= 0) 
      { 
       strPNameAndPValue = strEachCookParts[j]; 
       if (strPNameAndPValue != string.Empty) 
       { 
        NameValuePairTemp = strPNameAndPValue.Split('='); 
        if (NameValuePairTemp[1] != string.Empty) 
        { 
         cookTemp.Path = NameValuePairTemp[1]; 
        } 
        else 
        { 
         cookTemp.Path = "/"; 
        } 
       } 
       continue; 
      } 

      if (strEachCookParts[j].IndexOf("domain", StringComparison.OrdinalIgnoreCase) >= 0) 
      { 
       strPNameAndPValue = strEachCookParts[j]; 
       if (strPNameAndPValue != string.Empty) 
       { 
        NameValuePairTemp = strPNameAndPValue.Split('='); 

        if (NameValuePairTemp[1] != string.Empty) 
        { 
         cookTemp.Domain = NameValuePairTemp[1]; 
        } 
        else 
        { 
         cookTemp.Domain = strHost; 
        } 
       } 
       continue; 
      } 
     } 

     if (cookTemp.Path == string.Empty) 
     { 
      cookTemp.Path = "/"; 
     } 
     if (cookTemp.Domain == string.Empty) 
     { 
      cookTemp.Domain = strHost; 
     } 
     cc.Add(cookTemp); 
    } 
    return cc; 
}