2013-05-06 16 views
7

Trong HttpCookieCollection.Get MSDN documentation, nó được tuyên bố rằng:Tại sao HttpCookieCollection.Get trả về null khi gọi từ một đối tượng tự khởi tạo (và không phải từ HttpContext hiện hành)

Nếu cookie được đặt tên không tồn tại, phương pháp này tạo một cookie mới với tên đó.

Điều này đúng và hoạt động tốt khi gọi HttpContext.Request.Cookies hoặc HttpContext.Response.Cookies từ máy chủ web "thực".

Tuy nhiên, mã này:

HttpCookieCollection foo = new HttpCookieCollection(); 
    HttpCookie cookie = foo.Get("foo"); 
    Console.WriteLine(cookie != null); 

Hiển thị False (cookie là null).

Đây không phải là trường hợp nếu HttpCookieCollection được truy xuất từ ​​Request.Cookies trong trình xử lý HTTP.

Bất kỳ ý tưởng nào về sự cố ở đây/nếu cần thiết lập bất kỳ thiết lập nào khác?

Tôi hỏi điều này vì tôi viết các bài kiểm tra đơn vị nơi tôi giả sử HttpContextBase, vì vậy không có ngữ cảnh "thực" nào được cung cấp.

Cảm ơn bạn đã giúp đỡ của bạn

Trả lời

8

Nếu bạn nhìn vào các mã cho HttpCookieCollection.Get (string), bạn sẽ thấy một cái gì đó như thế này:

public HttpCookie Get(string name) 
{ 
    HttpCookie cookie = (HttpCookie) this.BaseGet(name); 
    if (cookie == null && this._response != null) 
    { 
    cookie = new HttpCookie(name); 
    this.AddCookie(cookie, true); 
    this._response.OnCookieAdd(cookie); 
    } 
    if (cookie != null) 
    this.EnsureKeyValidated(name, cookie.Value); 
    return cookie; 
} 

Nó không bao giờ tạo ra cookie vì _response là sẽ là null (nhìn vào câu lệnh 'if' đầu tiên). nghĩa là không có đối tượng phản hồi nào để gửi lại cookie mới, vì vậy nó sẽ không tạo ra nó.

Đối tượng phản hồi là đối tượng HttpResponse và nó được truyền qua cho hàm khởi tạo nội bộ (để hàm khởi tạo không sẵn dùng cho bạn).

Cá nhân tôi chưa bao giờ thích cách thức phương thức Get hoạt động trên HttpCookieCollection; vi phạm nguyên tắc Command-Query separation: đặt câu hỏi không nên thay đổi câu trả lời.

Tôi khuyên bạn nên kiểm tra sự tồn tại của cookie bằng cách kiểm tra thuộc tính AllKeys; nếu nó không tồn tại, hãy tạo và thêm cookie một cách rõ ràng vào bộ sưu tập. Nếu không, nếu bạn biết khóa tồn tại, hãy tiếp tục và tìm nạp mục nhập hiện có. Sau đó, mã sản xuất và kiểm tra đơn vị của bạn sẽ hoạt động.

Nó có thể là một ý tưởng tốt để tạo ra một helper hoặc mở rộng phương pháp để sử dụng thay vì Nhận, để đảm bảo nó cư xử như bạn mong đợi cho dù bạn đang kiểm tra đơn vị hoặc chạy bình thường:

public static class HttpCookieCollectionExtensions 
{ 
    public static HttpCookie GetOrCreateCookie(this HttpCookieCollection collection, string name) 
    { 
     // Check if the key exists in the cookie collection. We check manually so that the Get 
     // method doesn't implicitly add the cookie for us if it's not found. 
     var keyExists = collection.AllKeys.Any(key => string.Equals(name, key, StringComparison.OrdinalIgnoreCase)); 

     if (keyExists) return collection.Get(name); 

     // The cookie doesn't exist, so add it to the collection. 
     var cookie = new HttpCookie(name); 
     collection.Add(cookie); 
     return cookie; 
    } 
} 
Các vấn đề liên quan