2008-10-21 60 views
26

Đây có thể không phải là cách chính xác để sử dụng bộ điều khiển, nhưng tôi đã nhận thấy vấn đề này và đã không tìm ra cách sửa lỗi.HttpContext trên trường hợp của bộ điều khiển là null trong ASP.net MVC

public JsonResult SomeControllerAction() { 

    //The current method has the HttpContext just fine 
    bool currentIsNotNull = (this.HttpContext == null); //which is false  

    //creating a new instance of another controller 
    SomeOtherController controller = new SomeOtherController(); 
    bool isNull = (controller.HttpContext == null); // which is true 

    //The actual HttpContext is fine in both 
    bool notNull = (System.Web.HttpContext.Current == null); // which is false   

} 

Tôi đã nhận thấy rằng HttpContext trên bộ điều khiển không phải là "HttpContext" thực tế mà bạn sẽ tìm thấy trong System.Web.HttpContext.Current.

Có cách nào để tự điền HttpContextBase trên Bộ điều khiển không? Hoặc một cách tốt hơn để tạo ra một thể hiện của một Controller?

Trả lời

24

Bộ điều khiển không được thiết kế để tạo theo cách thủ công như bạn đang làm. Nghe có vẻ như những gì bạn thực sự nên làm là đặt bất kỳ logic tái sử dụng nào bạn có vào lớp trợ giúp thay thế.

+1

Brad, bạn có một nơi nào đó có thể giúp hiểu về thiết kế MVC và các phương pháp hay nhất? MVC đã được mát mẻ cho đến nay, nhưng hầu hết các ví dụ tôi đã tìm thấy không phải là rất phức tạp. Họ chỉ đi qua các trường hợp đơn giản như cập nhật một bản ghi duy nhất. – Hugoware

+0

Brad, tôi có cùng một vấn đề, và điều này cũng đến từ một lớp trợ giúp, giống như bạn đã đề nghị. Tôi đã thử sửa chữa được cung cấp bởi Hugoware (dưới đây), và cố định nó. Đây có phải là cách thích hợp để thực hiện việc này không? –

0

Có phải bạn muốn sử dụng một số chức năng từ bộ điều khiển không? Hoặc có bộ điều khiển thực hiện một hành động?

Nếu đó là tên cũ, có thể đó là một số mã nên được tách ra thành một lớp khác. Nếu đó là sau này, bạn có thể làm điều này để chỉ cần có điều khiển đó làm một hành động cụ thể:

 

return RedirectToAction("SomeAction", "SomeOtherController", new {param1 = "Something" }); 
 
5

HttpContext, trong ControllerContext là null vì nó không được thiết lập khi bộ điều khiển được tạo ra. Các contructor của bộ điều khiển không chỉ định tài sản này, do đó, nó sẽ được null. Thông thường, HttpContext được đặt thành HttpContext của lớp ControllerBuilder. Bộ điều khiển được tạo ra bởi lớp ControllerBuilder, tiếp theo là DefaultControllerFactory. Khi bạn muốn tạo một thể hiện riêng của bộ điều khiển, bạn có thể sử dụng ExecuteMethod của bộ điều khiển với ControllerContext của riêng bạn. Bạn không muốn làm điều đó là một ứng dụng thực sự. Khi bạn có thêm một số kinh nghiệm với khung công tác, bạn sẽ tìm thấy phương pháp thích hợp để làm những gì bạn muốn. Khi bạn cần ControllerContext trong bài kiểm tra đơn vị, bạn có thể sử dụng một khuôn khổ mocking để giả lập ControllerContext hoặc bạn có thể lớp giả mạo nó.

Bạn có thể tìm thấy mô hình luồng yêu cầu trong asp.net mvc trên this blog.

Khi bạn mới dùng Asp.net mvc, bạn nên tải xuống mã nguồn và đọc theo dõi cách thức xử lý yêu cầu.

0

Bạn đang sử dụng nhà máy điều khiển? Nếu vậy, bạn đăng ký thành phần như thế nào?

Tôi đã gặp phải vấn đề này, trong đó tôi đã vô tình thêm một phụ thuộc dựa trên HttpContext làm Singleton, thay vì Transient trong Windsor.

HttpContext là null cho tất cả trừ yêu cầu đầu tiên. Phải mất một thời gian tôi mới tìm được cái đó.

61

Hiện tại tôi sẽ làm như sau. Đây có vẻ là một sửa chữa có thể chấp nhận ...

public new HttpContextBase HttpContext { 
    get { 
     HttpContextWrapper context = 
      new HttpContextWrapper(System.Web.HttpContext.Current); 
     return (HttpContextBase)context;     
    } 
} 

đâu này sẽ được thêm vào một lớp điều khiển các bộ điều khiển được kế thừa từ.

Tôi không chắc liệu HttpContext có rỗng không là hành vi mong muốn, nhưng điều này sẽ khắc phục nó trong thời gian chờ đợi cho tôi.

+0

Cảm ơn bạn rất nhiều vì đã giải mã cách làm việc mới giữa hai loại. Tôi đã có một lớp học cũ tôi đã cố gắng sử dụng từ một bộ điều khiển MVC tiêu thụ một đối tượng HttpContext.Bây giờ tôi có một lớp tiêu thụ một đối tượng HttpContextBase với một quá tải xây dựng sẽ chuyển đổi giữa HttpContext và HttpContextBase bằng cách sử dụng hàm tạo HttpContextWrapper mà bạn đã đề cập. – patridge

+0

Vâng, tôi cũng muốn cảm ơn vì đã giải mã điều này! – Funka

+0

+1 Bài đăng tuyệt vời. Đã tìm kiếm điều này. – magnus

Các vấn đề liên quan