سؤال

لقد استخدمت مسبقًا CookieContainer مع جلسات httpwebrequest و httpwebropsebonse ، ولكن الآن ، أريد استخدامه مع ويب. بقدر ما أفهم ، لا توجد طريقة مدمجة مثل HTTPWebRequests (request.CookieContainer). كيف يمكنني جمع ملفات تعريف الارتباط من ويب في cookieContainer؟

أنا غوغليت لهذا ووجد العينة التالية:

public class CookieAwareWebClient : WebClient
{
    private readonly CookieContainer m_container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        HttpWebRequest webRequest = request as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.CookieContainer = m_container;
        }
        return request;
    }
}

هل هذه هي أفضل طريقة للقيام بذلك؟

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

المحلول

نعم. IMHO ، GetWebRequest () هو أفضل حل لوظيفة WebClient المحدودة. قبل أن أعرف عن هذا الخيار ، كتبت الكثير من التعليمات البرمجية المؤلمة حقًا في طبقة HTTPWebRequest لأن WebClient تقريبًا ، ولكن ليس تمامًا ، فعلت ما أحتاجه. الاشتقاق أسهل بكثير.

هناك خيار آخر هو استخدام فئة WebClient العادية ، ولكن يدويًا تملأ رأس ملف تعريف الارتباط قبل تقديم الطلب ثم سحب رأس المكونات المكتوبة على الاستجابة. هناك طرق مساعدة في فئة CookieContainer التي تجعل إنشاء هذه الرؤوس وتحليلها أسهل: CookieContainer.SetCookies() و CookieContainer.GetCookieHeader(), ، على التوالى.

أفضل النهج السابق لأنه أسهل بالنسبة للمتصل ويتطلب رمزًا أقل تكرارًا من الخيار الثاني. أيضًا ، يعمل نهج الاشتقاق بنفس الطريقة لسيناريوهات التوسيع المتعددة (مثل ملفات تعريف الارتباط ، الوكلاء ، إلخ).

نصائح أخرى

 WebClient wb = new WebClient();
 wb.Headers.Add(HttpRequestHeader.Cookie, "somecookie");

من التعليقات

كيف يمكنك تنسيق اسم وقيمة ملف تعريف الارتباط بدلاً من "Somecookie"؟

wb.Headers.Add(HttpRequestHeader.Cookie, "cookiename=cookievalue"); 

لملفات تعريف الارتباط المتعددة:

wb.Headers.Add(HttpRequestHeader.Cookie, 
              "cookiename1=cookievalue1;" +
              "cookiename2=cookievalue2");

هذا هو مجرد امتداد للمقال الذي وجدته.


public class WebClientEx : WebClient
{
    public WebClientEx(CookieContainer container)
    {
        this.container = container;
    }

    public CookieContainer CookieContainer
        {
            get { return container; }
            set { container= value; }
        }

    private CookieContainer container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest r = base.GetWebRequest(address);
        var request = r as HttpWebRequest;
        if (request != null)
        {
            request.CookieContainer = container;
        }
        return r;
    }

    protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
    {
        WebResponse response = base.GetWebResponse(request, result);
        ReadCookies(response);
        return response;
    }

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse response = base.GetWebResponse(request);
        ReadCookies(response);
        return response;
    }

    private void ReadCookies(WebResponse r)
    {
        var response = r as HttpWebResponse;
        if (response != null)
        {
            CookieCollection cookies = response.Cookies;
            container.Add(cookies);
        }
    }
}

يقوم HTTPWebRequest بتعديل CookieContainer المخصص له. ليست هناك حاجة لمعالجة ملفات تعريف الارتباط التي تم إرجاعها. ما عليك سوى تعيين حاوية ملفات تعريف الارتباط إلى كل طلب ويب.

public class CookieAwareWebClient : WebClient
{
    public CookieContainer CookieContainer { get; set; } = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri uri)
    {
        WebRequest request = base.GetWebRequest(uri);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = CookieContainer;
        }
        return request;
    }
}

أعتقد أن هناك طريقة أنظف حيث لا يتعين عليك إنشاء ويب جديد (وستعمل مع مكتبات الطرف الثالث أيضًا)

internal static class MyWebRequestCreator
{
    private static IWebRequestCreate myCreator;

    public static IWebRequestCreate MyHttp
    {
        get
        {
            if (myCreator == null)
            {
                myCreator = new MyHttpRequestCreator();
            }
            return myCreator;
        }
    }

    private class MyHttpRequestCreator : IWebRequestCreate
    {
        public WebRequest Create(Uri uri)
        {
            var req = System.Net.WebRequest.CreateHttp(uri);
            req.CookieContainer = new CookieContainer();
            return req;
        }
    }
}

الآن كل ما عليك فعله هو اختيار المجالات التي تريد استخدامها:

    WebRequest.RegisterPrefix("http://example.com/", MyWebRequestCreator.MyHttp);

هذا يعني أن أي WebRequest يذهب إلى example.com سيستخدم الآن منشئ WebRequest المخصص ، بما في ذلك WebClient القياسي. هذا النهج يعني أنه ليس عليك لمس كل رمزك. يمكنك فقط الاتصال ببادئة التسجيل مرة واحدة ويتم ذلك. يمكنك أيضًا التسجيل للحصول على بادئة "HTTP" للاختيار لكل شيء في كل مكان.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top