2009-06-30 43 views
20

Tôi nghĩ rằng MvcApplication là toàn cầu singleton. Tôi muốn có được ví dụ của MvcApplication trong bộ điều khiển. Sau đó, tôi đưa đoạn mã sau vào điều khiển:Làm thế nào để có được một trường hợp 'MvcApplication' trong bộ điều khiển ASP.NET?

MvcApplication app = HttpContext.Current.Application as MvcApplication; 

Nó mang lại cho tôi một lỗi:

Error 2 'System.Web.HttpContextBase' does not contain a definition for 'Current' and no extension method 'Current' accepting a first argument of type 'System.Web.HttpContextBase' could be found (are you missing a using directive or an assembly reference?)

Tại sao? Làm cách nào để truy cập MvcApplication trong bộ điều khiển?

+0

Bạn có thể giải thích điều bạn đang cố đạt được với điều này không? Có thể có một cách khác, thậm chí tốt hơn, để hoàn thành nhiệm vụ. – griegs

+0

những gì tôi muốn là: với ứng dụng mvc của tôi, tôi muốn nhận được giá trị chuỗi truy vấn khi người dùng truy cập vào trang chủ như: http: // localhost: 2929 /? Source = abc. thì tôi muốn đặt nguồn này = abc trong MvcApplication. lớp công khai MvcỨng dụng: System.Web.HttpApplication { Nguồn chuỗi công khai; // ..... } Sau đó, tôi muốn để nguồn có sẵn cho tất cả các quan điểm: Tôi muốn tiếp cận nguồn trong constructor điều khiển như: MvcApplication ứng dụng = HttpContext.Current.Application như MvcApplication chuỗi Src = app.Source ; ... – KentZhou

+2

Cảnh báo: Trước khi rời khỏi chủ đề này với câu trả lời được đánh dấu, hãy đọc câu trả lời của tôi bên dưới, vì các anwers khác, bao gồm cả dấu được đánh dấu, tất cả đều dựa trên giả định hoàn toàn sai rằng MvcApplication là một singleton toàn cầu. – citykid

Trả lời

31

Hãy thử điều này:

var app = HttpContext.ApplicationInstance as MvcApplication; 
+0

Tôi thử nó trong hàm tạo của bộ điều khiển như:
var app = HttpContext.ApplicationInstance as MvcApplication;
sau đó tôi gặp lỗi trong trang:
Lỗi máy chủ trong ứng dụng '/'.
....
Dòng 35: var app = HttpContext.ApplicationInstance as MvcApplication; – KentZhou

+0

Bạn nên tránh truy cập các thuộc tính của trình điều khiển như HttpContext hoặc ControllerContext trong hàm tạo. Hãy thử tương tự trong Hành động hoặc OnActionExecuting() –

16

Tôi tin rằng lý do tại sao mã gốc đã không làm việc là vì HttpContext là cả một tài sản của bộ điều khiển và lớp riêng của mình. Trong một lớp con của Controller, HttpContext sẽ giải quyết cho thuộc tính và tạo ra lỗi được đề cập. Để có được xung quanh nó, rõ ràng tham khảo các lớp HttpContext với nó là đầy đủ tên đủ điều kiện:

System.Web.HttpContext.Current.Application 

Hoặc, kể từ khi sở hữu HttpContext đã trả về HttpContext hiện tại Ví dụ, bạn có thể sử dụng:

HttpContext.Application 
40

MvcApplication! = singleton

có nghĩa là tất cả các câu trả lời ở trên đều thiếu điểm và sẽ khiến bạn gặp rắc rối nghiêm trọng nếu bạn tin tưởng sai khi truy cập cùng một trường hợp trong khi trong thực tế sẽ có một số.

Giả định đầu tiên của bạn không hợp lệ: Trái ngược với (rất - chỉ xem các câu trả lời khác ở đây là bằng chứng) niềm tin rộng rãi, MvcApplication KHÔNG phải là một singleton toàn cầu. Lớp được khởi tạo nhiều lần, một ví dụ cho mỗi "đường ống", vì vậy bộ đếm hiệu suất "số lượng đường ống dẫn" cho bạn biết có bao nhiêu phiên bản của MvcApplication hiện đang bị coi là còn sống. Thêm một ctor mặc định và tự chứng minh điều này:

public MvcApplication() 
{ 
    Trace.WriteLine(this.GetHashCode()); 
} 

Gỡ lỗi ngắt dòng hoặc xem các mã băm khác nhau trong DebugViewer. Để bắt buộc đếm số lượng đường dẫn tạo ra một phương thức với Thread.Sleep (5000), Asp.Net sau đó sẽ kích hoạt một cá thể mới khi bạn thực hiện một yêu cầu http khác song song.

Solution - Làm thế nào để nhanh chóng độc thân trong các ứng dụng Asp.Net (MVC hoặc WebForms)

Nếu lớp MvcApplication của bạn tuy nhiên có một phương pháp Application_Start() sau đó phương pháp này được gọi là trên thực tế chỉ một lần, quá trình rộng. Bạn có thể đặt các trường tĩnh ở đó. Đơn giản chỉ cần đặt chúng vào bất kỳ lớp nào, thường là MvcApplication là một lựa chọn thông thường tốt và truy cập chúng. Giống như

MvcApplication.MySingleValue = 72; 
MvcApplication.ActivePlayersCount = 3400; 
var n = MvcApplication.ActivePlayersCount; 
... 

HttpApplication weirdness

Thiết kế của lớp HttpApplication và các sự kiện của nó là khá kỳ lạ, mà có lẽ có lý do của nó trong một số loại lỏng lẻo của các khả năng tương thích ngược thiết kế để rất cũ COM dựa trang ASP. Có đối tượng ứng dụng thực tế chỉ được tạo ra một lần, chắc chắn là nguồn gốc của niềm tin sai liên quan đến Asp.Net.Ví dụ về sự kỳ lạ của HttpApplication:

protected void Application_Start() 
{ 
} 

Lưu ý rằng không có sự ghi đè nào liên quan! Tóm lại, các trường hợp ứng dụng có thể ít quan tâm đến hầu hết thời gian, tôi không thể thấy kịch bản nào có thể liên quan đến trạng thái giữ, vì trạng thái của nó sẽ được chia sẻ bởi một tập con tùy ý được xử lý. Vì vậy, truy cập nó theo cách hoàn toàn tốt như đã đề cập bởi Matt có thể không được yêu cầu quá thường xuyên.

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