Pregunta

Tengo un CookieContainer extraído de una sesión HttpWebRequest / HttpWebResponse llamado CookieJar . Quiero que mi solicitud para almacenar cookies entre ejecuciones, por lo que las cookies recogidos en el CookieContainer en una carrera del programa se utilizarán la próxima ejecución, también.

Creo que la manera de hacer esto sería escribir alguna manera el contenido de un CookieContainer en el disco. Mi pregunta es:

  • ¿Cómo se puede escribir CookieContainer en el disco ? ¿Hay funciones incorporadas para esto, o, si no es así, ¿cuáles son los enfoques de la gente ha tomado? ¿Hay clases disponibles para simplificar esto?
  • Una vez que usted ha escrito un CookieContainer en el disco, ¿Cómo se carga de nuevo en el uso de ?

ACTUALIZACIÓN: La primera respuesta ha sugerido serialización de la CookieContainer. Sin embargo, no estoy muy familiarizado con la forma de serializar y deserializar objetos tan complejos. Podría dar algunos código de ejemplo ? La sugerencia fue la de utilizar SOAPFormatter.

¿Fue útil?

Solución

Yo no lo he probado pero tiene el atributo Serializable y así puedo estar [de] serializado con la serialización binaria .NET, por ejemplo, SoapFormatter.

Aquí está el fragmento de código que pidió.

var formatter = new SoapFormatter();
string file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "cookies.dat"); 

using (Stream s = File.Create (file))
    formatter.Serialize(s, cookies);                            
...
CookieContainer retrievedCookies = null;
using (Stream s = File.OpenRead (file))
    retrievedCookies = (CookieContainer) formatter.Deserialize(s);

En cuanto a MSDN parece SoapFormatter ahora es obsoleto en .NET 3.5 y se recomienda que utilice BinaryFormatter. En el pasado he encontrado SoapFormatter útil que el archivo se puede leer que ayuda con el diagnóstico cuando se produce un error de deserialización! Estos formateadores son sensibles a los cambios de versión, incluso en la versión de ensamblado (por lo que si deserializar con una versión del marco de la actualización del marco, entonces puede que no deserializar, no estoy seguro), pero hay formas de evitar esto con la propiedad Carpeta si esto se convierte un problema. Creo que están diseñados principalmente para el corto plazo la persistencia / interacción remota, pero podrían ser lo suficientemente bueno para usted aquí.

El nuevo DataContractSerializer no parece trabajar con él por lo que está fuera.

Una alternativa sería la de escribir una clase CookieContainerData a [de] serializar con XmlSerializer y manualmente convertir entre esto y CookieContainer.

Otros consejos

Este problema me estaba molestando para las edades, nada que pudiera encontrar trabajado. He trabajado a cabo, por lo que poner esa información en el mundo.

Responder mediante la BinaryFormatter:

    public static void WriteCookiesToDisk(string file, CookieContainer cookieJar)
    {
        using(Stream stream = File.Create(file))
        {
            try {
                Console.Out.Write("Writing cookies to disk... ");
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, cookieJar);
                Console.Out.WriteLine("Done.");
            } catch(Exception e) { 
                Console.Out.WriteLine("Problem writing cookies to disk: " + e.GetType()); 
            }
        }
    }   

    public static CookieContainer ReadCookiesFromDisk(string file)
    {

        try {
            using(Stream stream = File.Open(file, FileMode.Open))
            {
                Console.Out.Write("Reading cookies from disk... ");
                BinaryFormatter formatter = new BinaryFormatter();
                Console.Out.WriteLine("Done.");
                return (CookieContainer)formatter.Deserialize(stream);
            }
        } catch(Exception e) { 
            Console.Out.WriteLine("Problem reading cookies from disk: " + e.GetType()); 
            return new CookieContainer(); 
        }
    }

Es interesante tener las cookies en formato de texto . Además de ser capaz de ser utilizado para escribir en el disco, que puede ser utilizado para otros fines.

funciona para mí!

Utilice las funciones LoadCookiesFromFile y SaveCookiesToFile para cargar y escribir las cookies en el disco, respectivamente.

O utilizar las funciones GetCookies y SetCookies a hacer lo mismo, pero a manipularla como una cadena.

CookieContainer cookieContainer = new CookieContainer();

void LoadCookiesFromFile(string path)
{
    SetCookies(cookieContainer, File.ReadAllText(path));
}

void SaveCookiesToFile(string path)
{
    File.WriteAllText(path, GetCookies(cookieContainer));
}

string GetCookies(CookieContainer cookieContainer)
{
    using (MemoryStream stream = new MemoryStream())
    {
        new BinaryFormatter().Serialize(stream, cookieContainer);
        var bytes = new byte[stream.Length];
        stream.Position = 0;
        stream.Read(bytes, 0, bytes.Length);
        return Convert.ToBase64String(bytes);
    }
}

void SetCookies(CookieContainer cookieContainer, string cookieText)
{
    try
    {
        var bytes = Convert.FromBase64String(cookieText);
        using (MemoryStream stream = new MemoryStream(bytes))
        {
            cookieContainer = (CookieContainer)new BinaryFormatter().Deserialize(stream);
        }
    }
    catch
    {
        //Ignore if the string is not valid.
    }
}

Otra alternativa es utilizar la serialización JSON ( Json.NET ):

// other includes
using Newtonsoft.Json;

Una clase con una galleta:

public class WithCookie
{
    public Cookie MyCookie { get; set; }

    public WithCookie()
    {
        MyCookie = new Cookie("CF788DF", "A cookie value!", "/", ".test.com");
    }
}

Aquí es cómo serializarlo a JSON:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            WithCookie wc1 = new WithCookie();
            // Expires a month from now
            wc1.MyCookie.Expires = DateTime.Now.AddMonths(1);

            string wc1json = JsonConvert.SerializeObject(new WithCookie());

            WithCookie wc2 = JsonConvert.DeserializeObject < WithCookie>(wc1json);

            string wc2json = JsonConvert.SerializeObject(wc2);

            if (wc2json == wc1json)
            {
                Console.WriteLine("HORRAY!");
            }
            else
            {
                // The strings will not be equal, because the Cookie.TimeStamp 
                // changes but the cookies are in fact the same!
                Console.WriteLine("FAIL!");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: " + e.ToString());
        }
        Console.ReadKey();
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top