C#:将CookieContainer写入磁盘并重新加载以供使用

我有一个名为CookieJar的HttpWebRequest / HttpWebResponse会话中提取的CookieContainer 。 我希望我的应用程序在运行之间存储cookie,因此在一次运行程序中在CookieContainer收集的cookie也将在下一次运行时使用。

我认为这样做的方法是以某种方式将CookieContainer的内容写入磁盘。 我的问题是:

  • 如何将CookieContainer写入磁盘 ? 是否有内置function,或者,如果没有,人们采取了哪些方法? 有没有可用于简化此类的课程?
  • 一旦你将CookieContainer写入磁盘, 你如何重新加载它

更新:第一个答案建议CookieContainer 序列化 。 但是,我不太熟悉如何序列化和反序列化这些复杂的对象。 你能提供一些示例代码吗? 建议是使用SOAPFormatter

我没有尝试过,但它具有Seri​​alizable属性,因此可以使用.net二进制序列化[de]序列化,例如SoapFormatter。

这是您要求的代码段。

 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); 

看看msdn似乎现在在.net 3.5中不推荐使用SoapFormatter,它建议你使用Binaryformatter。 在过去,我发现SoapFormatter非常有用,因为该文件是可读的,这有助于在反序列化失败时进行诊断! 这些格式化程序对版本更改很敏感,即使在汇编版本中也是如此(因此,如果使用一个版本的框架反序列化升级框架,那么它可能不会反序列化,也不确定),但是如果这变成了Binder属性的话一个问题。 我相信它们主要是为短期持久性/远程设计而设计的,但它们对你来说可能已经足够好了。

新的DataContractSerializer似乎无法使用它,所以这是出来的。

另一种方法是将一个CookieContainerData类写入[de]使用XmlSerializer进行序列化,并在此和CookieContainer之间手动转换。

这个问题困扰了我多年,我找不到任何工作。 我把它解决了,所以把这些信息传播到世界各地。

使用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(); } } 

另一种方法是使用Json序列化( Json.NET ):

 // other includes using Newtonsoft.Json; 

带有cookie的类:

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

以下是将其序列化为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(); } }