Tôi nên làm gì nếu phiên ASP.NET hiện tại là rỗng?


125

Trong ứng dụng web của tôi, tôi làm điều gì đó như sau để đọc các biến phiên:

if (HttpContext.Current.Session != null &&  HttpContext.Current.Session["MyVariable"] != null)
{
    string myVariable= (string)HttpContext.Current.Session["MyVariable"];
}

Tôi hiểu tại sao điều quan trọng là phải kiểm tra tại sao HttpContext.Current.Session ["MyVariable"] là null (biến có thể chưa được lưu trữ trong Phiên hoặc Phiên đã được đặt lại vì nhiều lý do khác nhau), nhưng tại sao tôi cần kiểm tra nếu HttpContext.Current.Sessionlà null?

Sự hiểu biết của tôi là phiên được tạo tự động bởi ASP.NET do đó HttpContext.Current.Session không bao giờ được để trống. Giả thiết này có đúng không? Nếu nó có thể là null, có nghĩa là tôi cũng nên kiểm tra nó trước khi lưu trữ thứ gì đó trong đó:

if (HttpContext.Current.Session != null)
{
    HttpContext.Current.Session["MyVariable"]="Test";
}
else
{
    // What should be done in this case (if session is null)?
    // Is it possible to force the session to be created if it doesn't exist?
}

ASP.NET WebAPI sẽ có hành vi khác nhau, bạn có thể kiểm tra xem nó trên Truy cập phiên Sử dụng ASP.NET Web API
Tiago Gouvêa

Câu trả lời:


158

Có, đối tượng Session có thể là null, nhưng chỉ trong một số trường hợp nhất định, mà bạn hiếm khi gặp phải:

Nếu bạn chỉ có mã trong các trang, bạn sẽ không gặp phải vấn đề này. Hầu hết mã ASP .NET của tôi sử dụng Session mà không kiểm tra null nhiều lần. Tuy nhiên, đó là điều cần suy nghĩ nếu bạn đang phát triển IHttpModule hoặc nói cách khác là các chi tiết phức tạp hơn của ASP .NET.

Biên tập

Trả lời nhận xét: Trạng thái phiên khả dụng hay không phụ thuộc vào việc liệu sự kiện AcquireRequestState đã chạy cho yêu cầu hay chưa. Đây là nơi mô-đun trạng thái phiên hoạt động bằng cách đọc cookie phiên và tìm tập hợp các biến phiên phù hợp cho bạn.

AcquireRequestState chạy trước khi quyền kiểm soát được trao cho Trang của bạn. Vì vậy, nếu bạn đang gọi chức năng khác, bao gồm các lớp tĩnh, từ trang của mình, bạn sẽ ổn.

Nếu bạn có một số lớp thực hiện logic khởi tạo trong khi khởi động, ví dụ như trên sự kiện Application_Start hoặc bằng cách sử dụng hàm tạo tĩnh, trạng thái Phiên có thể không khả dụng. Tất cả chỉ đơn giản là có một yêu cầu hiện tại và AcquireRequestState đã được chạy hay chưa.

Ngoài ra, nếu máy khách đã tắt cookie, đối tượng Session sẽ vẫn có sẵn - nhưng trong yêu cầu tiếp theo, người dùng sẽ quay lại với một Session trống mới. Điều này là do máy khách được cấp một túi trạng thái Phiên nếu họ chưa có. Nếu khách hàng không vận chuyển cookie phiên, chúng tôi không có cách nào để xác định khách hàng là giống nhau, vì vậy họ sẽ được chuyển giao một phiên mới nhiều lần.


6
Chỉ là một bản cập nhật nhanh tôi tìm thấy hôm nay. Phiên không có sẵn trên phương thức tạo trang! Chỉ trong sự kiện Init hoặc sau đó.
Nuno Agapito

Tôi vừa gặp phải HttpContext.Current.Session == null là mã được gọi bởi sự kiện Page_Load của một trang chính. Rõ ràng, điều này có thể xảy ra trong ngữ cảnh của một trang. Nếu tôi kiểm tra đối tượng HttpContext.Current, hầu hết các thành viên của nó đều được khởi tạo, nhưng CurrentNotification và IsPostNotification gặp lỗi: {System.PlatformNotSupportedException}. Cho dù nguyên nhân là gì, vấn đề này đã không xảy ra trong sản xuất, nơi nó đã chạy trong nhiều năm. Nền tảng là Windows Server 2003 R2 SP2, ứng dụng có khung đích .Net 3.5 và chạy trong IIS với trạng thái phiên được bật.
R. Schreurs

Tôi cũng nhận thấy rằng, khi IIS đang phục vụ yêu cầu trực tiếp cho tệp tài nguyên tồn tại trên đĩa, chẳng hạn như biểu định kiểu, HttpContext.Current.Sessioncó thể là rỗng đối với mã trong `Application_AcquireRequestState '. Tuy nhiên, yêu cầu cho chính trang đó làm cho đối tượng phiên có sẵn để viết mã ở đó. Điều này ít nhất là theo MVC.NET 4.
ingredient_15939

Tôi nghĩ rằng nó cũng có thể là null nếu bạn đang ở trong một hành động MVC được lưu vào bộ nhớ cache đầu ra.
user2173353

40

Tuyên bố sau đây không hoàn toàn chính xác:

"Vì vậy, nếu bạn đang gọi chức năng khác, bao gồm cả các lớp tĩnh, từ trang của mình, bạn sẽ ổn"

Tôi đang gọi một phương thức tĩnh tham chiếu đến phiên thông qua HttpContext.Current.Session và nó là null. Tuy nhiên, tôi đang gọi phương thức thông qua một phương thức webservice thông qua ajax bằng cách sử dụng jQuery.

Như tôi đã tìm ra ở đây, bạn có thể khắc phục sự cố bằng một thuộc tính đơn giản trên phương thức hoặc sử dụng đối tượng phiên dịch vụ web:

Tuy nhiên, có một mẹo nhỏ, để truy cập trạng thái phiên trong một phương pháp web, bạn phải bật quản lý trạng thái phiên như sau:

[WebMethod (EnableSession = true)]

Bằng cách chỉ định giá trị EnableSession, bây giờ bạn sẽ có một phiên được quản lý để chơi cùng. Nếu bạn không chỉ định giá trị này, bạn sẽ nhận được đối tượng Phiên rỗng và nhiều khả năng gặp phải các ngoại lệ tham chiếu rỗng trong khi cố gắng truy cập đối tượng phiên.

Cảm ơn Matthew Cozier về giải pháp.

Tôi chỉ nghĩ rằng tôi sẽ thêm hai xu của mình.

Ed


1
cảm ơn Ed, Phiên xuất hiện dưới dạng null trong webmethod - thêm điều này đã sửa nó. +1
fusi

1
Khi bạn đang gọi vào một dịch vụ web, bạn sử dụng một yêu cầu khác chứ không phải cho trang, vì vậy câu lệnh đó vẫn đúng, IMO.
driis

Tài liệu MSDN tại đây - the default value is false. Hoạt động như một sự quyến rũ.
Benjineer

22

Nếu phiên bản Session của bạn là null và của bạn trong tệp 'ashx', chỉ cần triển khai giao diện 'IRequiresSessionState'.

Giao diện này không có bất kỳ thành viên nào nên bạn chỉ cần thêm tên giao diện sau phần khai báo lớp (C #):

public class MyAshxClass : IHttpHandler, IRequiresSessionState

Cảm ơn bạn rất nhiều, phiên đã bị vô hiệu trong lớp đăng nhập của tôi. Khi tôi thêm mã này để xử lý ashx tôi nó bật phiên họp về lớp học của tôi quá
Ateş Danis

Tôi nghĩ điều này trả lời câu hỏi khá tốt. Cám ơn rất nhiều.
Sachin Joseph

2

Bài báo kỹ thuật ASP.NET

TÓM TẮT: Trong ASP.NET, mọi trang Web đều bắt nguồn từ lớp System.Web.UI.Page. Lớp Trang tổng hợp một thể hiện của đối tượng HttpSession cho dữ liệu phiên. Lớp Trang hiển thị các sự kiện và phương thức khác nhau để tùy chỉnh. Đặc biệt, phương thức OnInit được sử dụng để thiết lập trạng thái khởi tạo của đối tượng Trang. Nếu yêu cầu không có cookie Phiên, một cookie Phiên mới sẽ được cấp cho người yêu cầu.

BIÊN TẬP:

Phiên: Khái niệm cho người mới bắt đầu

TÓM TẮT: Phiên được tạo khi người dùng gửi yêu cầu đầu tiên đến máy chủ cho bất kỳ trang nào trong ứng dụng web, ứng dụng tạo Phiên và gửi lại Session ID cho người dùng cùng với phản hồi và được lưu trữ trong máy khách dưới dạng một cookie nhỏ . Vì vậy, lý tưởng nhất là "máy đã tắt cookie, thông tin phiên sẽ không được lưu trữ".


2

Trong trường hợp của tôi ASP.NET State Serviceđã được dừng lại. Thay đổi Startup typethành Automaticvà bắt đầu dịch vụ theo cách thủ công lần đầu tiên đã giải quyết được sự cố.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.