c# file-io cookies httpwebrequest cookiecontainer

C#: Escribir un CookieContainer en el disco y volver a cargarlo para su uso



file-io cookies (3)

Tengo un CookieContainer extraído de una sesión HttpWebRequest / HttpWebResponse llamada CookieJar . Quiero que mi aplicación almacene cookies entre ejecuciones, por lo que las cookies recopiladas en el CookieContainer en una ejecución del programa también se usarán en la próxima ejecución.

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

  • ¿Cómo se puede escribir un CookieContainer en el disco ? ¿Hay funciones incorporadas para esto, o, si no, cuáles son los enfoques que las personas han tomado? ¿Hay alguna clase disponible para simplificar esto?
  • Una vez que haya escrito un CookieContainer en el disco, ¿cómo lo vuelve a cargar para usarlo ?

ACTUALIZACIÓN: la primera respuesta ha sugerido la serialización del CookieContainer . Sin embargo, no estoy muy familiarizado con la forma de serializar y deserializar tales objetos complejos. ¿Podría proporcionar algún código de muestra ? La sugerencia fue utilizar SOAPFormatter .


Este problema me estaba molestando por años, nada de lo que pude encontrar funcionó. Lo resolví, así que sacando esa información al mundo.

Responda usando 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(); } }


No lo he probado, pero tiene el atributo Serializable y, por lo tanto, puede [de] serializarse con serialización binaria .net, por ejemplo, SoapFormatter.

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

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 que SoapFormatter ahora está en desuso en .net 3.5 y recomienda que uses Binaryformatter. En el pasado, he encontrado que SoapFormatter es útil ya que el archivo es legible, lo que ayuda al diagnóstico cuando falla la deserialización. Estos formateadores son sensibles a los cambios de versión incluso en la versión de ensamblaje (por lo que si deserializa con una versión del marco, actualice el marco, entonces puede que no se deserialice, no está seguro), pero hay formas de evitar esto con la propiedad Binder. un problema. Creo que están diseñados principalmente para la persistencia / interacción a corto plazo, pero podrían ser lo suficientemente buenos para ti aquí.

El nuevo DataContractSerializer no parece funcionar con él, así que está apagado.

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


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

// other includes using Newtonsoft.Json;

Una clase con una cookie:

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

Aquí está 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(); } }