2012-06-22 30 views
20

Tôi cố gắng để kiểm tra đơn vị một số mã, và tôi cần phải thay thế này:Làm cách nào để thêm cookie vào WebRequest?

HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri); 
    httpWebRequest.CookieContainer = new CookieContainer(); 

với

WebRequest webRequest = WebRequest.Create(uri); 
    webRequest.CookieContainer = new CookieContainer(); 

Về cơ bản, làm thế nào để tôi nhận được các tập tin cookie vào yêu cầu mà không cần sử dụng một HttpWebRequest?

+0

Điều đó sẽ rất khó, vì cookie là một khái niệm HTTP. Có lý do nào bạn cần thực hiện thay đổi này không? – dlev

+0

@dlev - WebRequest sẽ tạo một HttpWebRequest dựa trên uri. Do đó, nếu tôi muốn giả lập đối tượng WebRequest của riêng tôi và/hoặc đăng ký uri của riêng tôi cũng trả về một WebRequest, thì tôi không muốn hạn chế phương thức chỉ làm việc với một đối tượng HttpWebRequest. –

+1

Tôi hiểu rằng kiểu chạy 'webRequest' sẽ là' HttpWebRequest'. Nhưng việc truy cập 'CookieContainer' yêu cầu kiểu thời gian biên dịch là' HttpWebRequest'. Ngoài ra, bạn đề cập đến việc không ràng buộc bản thân với HTTP, nhưng trong trường hợp đó, cookie không có ý nghĩa nhiều, vì chúng là một cấu trúc HTTP (đó là lý do cho sự vắng mặt của chúng trên 'WebRequest' ngay từ đầu.) – dlev

Trả lời

22

Dựa trên ý kiến ​​của bạn, bạn có thể xem xét viết một extension method:

public static bool TryAddCookie(this WebRequest webRequest, Cookie cookie) 
{ 
    HttpWebRequest httpRequest = webRequest as HttpWebRequest; 
    if (httpRequest == null) 
    { 
     return false; 
    } 

    if (httpRequest.CookieContainer == null) 
    { 
     httpRequest.CookieContainer = new CookieContainer(); 
    } 

    httpRequest.CookieContainer.Add(cookie); 
    return true; 
} 

Sau đó, bạn có thể có mã như:

WebRequest webRequest = WebRequest.Create(uri); 
webRequest.TryAddCookie(new Cookie("someName","someValue")); 
+1

Mã này trả về: "Tham số '{0}' không thể là một chuỗi rỗng." trên dòng httpRequest.CookieContainer.Add (cookie) ;. Bất kỳ ý tưởng? –

+2

@drdigit Đó là vì bạn không tạo cookie bao gồm tên miền. Ngoài ra, tôi khá chắc chắn chuỗi lỗi là một lỗi trong BCL (mà, không may, dường như đã tồn tại trong 4.5) – dlev

+0

Cảm ơn rất nhiều cho trả lời chi tiết. –

3

Hãy thử với một cái gì đó như thế này:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/default.html"); 
request.CookieContainer.Add(new Cookie("ConstoCookie", "Chocolate Flavour")); 
+0

Câu hỏi không phải là về việc đặt cookie thành Trả lời.Đó là về Tạo WebRequest mới và thiết lập một cookie cho yêu cầu này (và xem các thẻ của câu hỏi, thực hiện yêu cầu từ bài kiểm tra đơn vị). –

+2

điều này sẽ ném một lỗi 'Tham chiếu đối tượng không được đặt thành ...'. Đầu tiên chúng ta có thể cần 'request.CookieContainer = new CookieContainer();' sau đó gọi phương thức Add sẽ hoạt động. – shashwat

6

WebRequest là một lớp trừu tượng không có thuộc tính CookieContainer. Ngoài ra, bạn không thể sử dụng bộ sưu tập Tiêu đề (không được thực hiện ngoại lệ) nên mọi nỗ lực như webRequest.Headers.Add ("Cookie", "...") sẽ không thành công.

Xin lỗi, nhưng bạn không có cơ hội sử dụng cookie với WebRequest.

Gắn trên HttpWebRequest và thêm/chỉnh sửa bao nhiêu cookie bạn thích bằng cách sử dụng bộ sưu tập Tiêu đề của nó!

+0

Đó là điều tôi sợ. –

+0

Tôi đã không làm điều đó :) Yêu cầu "nếu sau đó addcookies" của bạn có thể được bao phủ bởi HttpWebRequest.Headers.Add ("Cookie", "..."). –

0

Câu trả lời của dlev đã kết thúc, nhưng tôi đã gặp sự cố khi triển khai giải pháp ("Tham số '{0}' không thể là chuỗi trống"), vì vậy tôi quyết định viết mã đầy đủ trong trường hợp bất kỳ ai khác có vấn đề tương tự .

Mục tiêu của tôi là nhận html dưới dạng chuỗi, nhưng tôi cần thêm cookie vào yêu cầu web. Đây là chức năng mà tải các chuỗi bằng cách sử dụng các tập tin cookie:

public static string DownloadString(string url, Encoding encoding, IDictionary<string, string> cookieNameValues) 
{ 
    using (var webClient = new WebClient()) 
    { 
     var uri = new Uri(url); 
     var webRequest = WebRequest.Create(uri); 
     foreach(var nameValue in cookieNameValues) 
     { 
      webRequest.TryAddCookie(new Cookie(nameValue.Key, nameValue.Value, "/", uri.Host)); 
     }     
     var response = webRequest.GetResponse(); 
     var receiveStream = response.GetResponseStream(); 
     var readStream = new StreamReader(receiveStream, encoding); 
     var htmlCode = readStream.ReadToEnd();     
     return htmlCode; 
    } 
} 

Chúng tôi đang sử dụng mã từ câu trả lời dlev của:

public static bool TryAddCookie(this WebRequest webRequest, Cookie cookie) 
{ 
    HttpWebRequest httpRequest = webRequest as HttpWebRequest; 
    if (httpRequest == null) 
    { 
     return false; 
    } 

    if (httpRequest.CookieContainer == null) 
    { 
     httpRequest.CookieContainer = new CookieContainer(); 
    } 

    httpRequest.CookieContainer.Add(cookie); 
    return true; 
} 

Đây là cách bạn sử dụng mã đầy đủ:

var cookieNameValues = new Dictionary<string, string>(); 
cookieNameValues.Add("varName", "varValue"); 
var htmlResult = DownloadString(url, Encoding.UTF8, cookieNameValues); 
Các vấn đề liên quan