C#: كتابة cookiecontainer إلى القرص والتحميل مرة أخرى للاستخدام

StackOverflow https://stackoverflow.com/questions/1777203

سؤال

انا املك CookieContainer تم استخراجها من جلسة httpwebrequest/httpwebropsponse وعاء البسكويت. أريد تطبيقي لتخزين ملفات تعريف الارتباط بين الركض ، لذا تم جمع ملفات تعريف الارتباط في CookieContainer في مجموعة واحدة من البرنامج سيتم استخدام التشغيل التالي أيضًا.

أعتقد أن الطريقة للقيام بذلك ستكون لكتابة محتويات cookiecontainer بطريقة ما إلى القرص. سؤالي هو:

  • كيف يمكنك اكتب cookiecontainer إلى القرص؟ هل هناك وظائف مدمجة لهذا ، أو ، إن لم يكن ، ما هي الأساليب التي اتخذها الناس؟ هل هناك أي فصول متاحة لتبسيط هذا؟
  • بمجرد أن تكتب cookiecontainer إلى القرص ، كيف يمكنك تحميله مرة أخرى للاستخدام?

تحديث: اقترح الجواب الأول التسلسل التابع CookieContainer. ومع ذلك ، لست على دراية بكيفية تسلسل هذه الأشياء المعقدة وتهرب من ذلك. هل يمكنك تقديم بعض عينة من الرموز؟ كان الاقتراح هو الاستفادة SOAPFormatter.

هل كانت مفيدة؟

المحلول

لم أجربها ولكن لديها السمة قابلة للتسلسل ، وبالتالي يمكن [de] تسلسل مع .NET التسلسل الثنائي ، على سبيل المثال الصابون.

هنا هو مقتطف الرمز الذي طلبته.

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 ، يبدو أنه تم إهمال Soapformatter الآن في .NET 3.5 ويوصيك باستخدام ثنائية التكافؤ. في الماضي ، وجدت صابونًا مفيدًا لأن الملف قابل للقراءة والذي يساعد في التشخيص عند فشل هجر! هذه التنسيقات حساسة لتغييرات الإصدار حتى في إصدار التجميع (لذلك إذا قمت بتهرب من إصدار واحد من إطار عمل الإطار ، فإنه قد لا يهدأ ، غير متأكد) ، ولكن هناك طرق حول هذا مع خاصية Binder إذا أصبح هذا مشكلة. أعتقد أنها مصممة بشكل أساسي من أجل الاستمرار / البعيد على المدى القصير ، لكنها قد تكون جيدة بما يكفي لك هنا.

لا يبدو أن DataContractSerializer الجديد يعمل مع ذلك.

سيكون البديل هو كتابة فئة CookieContainerData لتسلسلها مع XmlSerializer وتحويلها يدويًا بين هذا و CookieContainer.

نصائح أخرى

كانت هذه المشكلة تزعجني على مر العصور ، لا شيء يمكنني العثور عليه. لقد عملت عليها ، لذا وضع هذه المعلومات في العالم.

الإجابة باستخدام ثنائية التكافؤ:

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

من المثير للاهتمام أن يكون ملفات تعريف الارتباط في تنسيق النص. إلى جانب القدرة على استخدامها للكتابة إلى القرص ، يمكن استخدامه لأغراض أخرى.

تناسبني!

استخدم ال LoadCookiesFromFile و SaveCookiesToFile وظائف لتحميل وكتابة ملفات تعريف الارتباط على القرص على التوالي.

أو استخدم GetCookies و SetCookies وظائف لفعل الشيء نفسه ، ولكن لمعالجة ذلك كسلسلة.

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.
    }
}

بديل آخر هو استخدام تسلسل JSON (json.net):

// other includes
using Newtonsoft.Json;

فصل مع ملف تعريف الارتباط:

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();
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top