Cách tốt nhất để xác định biến phiên là null hay rỗng trong C # là gì?


79

Cách tốt nhất để kiểm tra sự tồn tại của biến phiên trong ASP.NET C # là gì?

Tôi thích sử dụng String.IsNullOrEmpty()các tác phẩm cho chuỗi và tự hỏi liệu có một phương pháp tương tự cho Session. Hiện tại, cách duy nhất tôi biết là:

 var session;
 if (Session["variable"] != null)
 {
     session = Session["variable"].ToString();
 }
 else
 {
     session = "set this";
     Session["variable"] = session;
 }

Câu trả lời:


114

Để làm theo những gì người khác đã nói. Tôi có xu hướng có hai lớp:

Lớp lõi. Điều này nằm trong một DLL được thêm vào gần như tất cả các dự án ứng dụng web . Trong phần này, tôi có một lớp SessionVars mà grunt hoạt động cho getters / setters trạng thái phiên. Nó chứa mã như sau:

public class SessionVar
{
    static HttpSessionState Session
    {
        get
        {
            if (HttpContext.Current == null)
                throw new ApplicationException("No Http Context, No Session to Get!");

            return HttpContext.Current.Session;
        }
    }

    public static T Get<T>(string key)
    {
        if (Session[key] == null)
            return default(T);
        else
            return (T)Session[key];
    }

    public static void Set<T>(string key, T value)
    {
        Session[key] = value;
    }
}

Lưu ý các yếu tố chung để nhận bất kỳ loại nào.

Sau đó, tôi cũng thêm Getters / Setters cho các loại cụ thể, đặc biệt là chuỗi vì tôi thường thích làm việc với string.Empty hơn là null cho các biến được hiển thị cho Người dùng.

ví dụ:

public static string GetString(string key)
{
    string s = Get<string>(key);
    return s == null ? string.Empty : s;
}

public static void SetString(string key, string value)
{
    Set<string>(key, value);
}

Và như thế...

Sau đó, tôi tạo các trình bao bọc để trừu tượng hóa nó và đưa nó lên mô hình ứng dụng. Ví dụ: nếu chúng tôi có thông tin chi tiết về khách hàng:

public class CustomerInfo
{
    public string Name
    {
        get
        {
            return SessionVar.GetString("CustomerInfo_Name");
        }
        set
        {
            SessionVar.SetString("CustomerInfo_Name", value);
        }
    }
}

Bạn hiểu ý tưởng phải không? :)

LƯU Ý: Chỉ cần suy nghĩ khi thêm nhận xét vào câu trả lời được chấp nhận. Luôn đảm bảo các đối tượng có thể tuần tự hóa khi lưu trữ chúng trong Session khi sử dụng máy chủ trạng thái. Có thể quá dễ dàng để thử và lưu một đối tượng bằng cách sử dụng generic khi ở trên trang web và nó phát triển vượt bậc. Tôi triển khai trên trang trại web tại nơi làm việc nên đã thêm các kiểm tra vào mã của tôi trong lớp lõi để xem liệu đối tượng có thể tuần tự hóa hay không, một lợi ích khác của việc đóng gói Trình nhận phiên và Trình thiết lập :)


Cách tiếp cận tuyệt vời! Tôi đã sử dụng một cái gì đó tương tự trong một thời gian dài, nhưng không kết hợp thuốc chung. Điều này tránh rất nhiều vấn đề với các nhà phát triển khác nhau khi tạo các biến Phiên tương tự.
DOK

Tôi có thể làm như thế nào để xử lý các ngoại lệ nếu "ném ApplicationException mới (" Không có ngữ cảnh Http, Không có phiên nào để tải! ");" được thực thi ?, Tôi đang nhầm lẫn về Thuộc tính Tự động Triển khai, Trong phần này của mã, tôi có thể nhận được ngoại lệ khi xảy ra.
Marztres

Cách tiếp cận tốt. Tôi đang gặp sự cố khi triển khai điều này trong Thư viện Lớp C #. Tôi không thể giải quyết các tham chiếu đến HttpSessionState/ HttpContext. Bạn có phải cài đặt thư viện MVC trong DLL để nhập không gian tên thích hợp không?
seebiscuit

18

Đó là khá nhiều cách bạn làm điều đó. Tuy nhiên, có một cú pháp ngắn hơn mà bạn có thể sử dụng.

sSession = (string)Session["variable"] ?? "set this";

Điều này nói lên rằng nếu các biến phiên là null, hãy đặt sSession thành "set this"


1
bạn không thể làm điều này ... Session ["biến"] là một đối tượng và trình biên dịch sau đó sẽ chuyển đổi nó thành một chuỗi vì sSession là một chuỗi, nếu Session ["biến"] không tồn tại, nó sẽ ném ra một ngoại lệ !
balexandre 24/10/08

Bạn hoàn toàn chính xác. Tôi đã cập nhật mã để truyền chuỗi nếu Phiên không rỗng.
Ely

14

Nó có thể làm cho mọi thứ trở nên thanh lịch hơn khi bọc nó trong một tài sản.

string MySessionVar
{
   get{
      return Session["MySessionVar"] ?? String.Empty;
   }
   set{
      Session["MySessionVar"] = value;
   }
}

thì bạn có thể coi nó như một chuỗi.

if( String.IsNullOrEmpty( MySessionVar ) )
{
   // do something
}

Đây là những gì tôi làm, giúp việc truy cập các giao diện phiên trong một ứng dụng dễ dàng hơn nhiều. Tôi có xu hướng tạo các lớp cho dữ liệu và các thuộc tính tĩnh thực hiện tất cả các công việc grunt kiểm tra null.
Rob Cooper

Điều gì sẽ xảy ra nếu bạn đang lưu trữ một đối tượng trong Session và không chỉ là một chuỗi?
Aaron Palmer

1
Hãy xem câu trả lời của tôi, việc sử dụng generic cho phép an toàn kiểu khi lưu trữ các đối tượng khác.
Rob Cooper

? Excuse me, là 'Session ( "' phần đúng tôi nhận lỗi.
Chúa Giêsu Zamora

Nó sẽ có trong VB. :) đã thay đổi thành dấu ngoặc vuông.
Greg Ogle

8

Ký hiệu 'as' trong c # 3.0 rất rõ ràng. Vì tất cả các biến phiên đều là đối tượng nullable, điều này cho phép bạn lấy giá trị và đặt nó vào biến đã nhập của riêng bạn mà không phải lo lắng về việc ném ra một ngoại lệ. Hầu hết các đối tượng có thể được xử lý theo cách này.

string mySessionVar = Session["mySessionVar"] as string;

Khái niệm của tôi là bạn nên kéo các biến Phiên của mình thành các biến cục bộ và sau đó xử lý chúng một cách thích hợp. Luôn giả sử các biến Phiên của bạn có thể là giá trị rỗng và không bao giờ chuyển chúng thành kiểu không thể null.

Nếu bạn cần một biến được nhập không thể nullable, bạn có thể sử dụng TryParse để có được điều đó.

int mySessionInt;
if (!int.TryParse(mySessionVar, out mySessionInt)){
   // handle the case where your session variable did not parse into the expected type 
   // e.g. mySessionInt = 0;
}

2

Theo tôi, cách dễ nhất để làm điều này rõ ràng và dễ đọc là:

 String sVar = (string)(Session["SessionVariable"] ?? "Default Value");

Nó có thể không phải là phương pháp hiệu quả nhất, vì nó truyền giá trị chuỗi mặc định ngay cả trong trường hợp mặc định (truyền một chuỗi dưới dạng chuỗi), nhưng nếu bạn biến nó thành phương pháp mã hóa tiêu chuẩn, bạn sẽ thấy nó hoạt động với tất cả các kiểu dữ liệu, và dễ đọc.

Ví dụ (một ví dụ hoàn toàn không có thật, nhưng nó chỉ ra điểm chính):

 DateTime sDateVar = (datetime)(Session["DateValue"] ?? "2010-01-01");
 Int NextYear = sDateVar.Year + 1;
 String Message = "The Procrastinators Club will open it's doors Jan. 1st, " +
                  (string)(Session["OpeningDate"] ?? NextYear);

Tôi thích tùy chọn Generics, nhưng nó có vẻ như quá mức cần thiết trừ khi bạn mong đợi cần điều này ở khắp nơi. Phương thức mở rộng có thể được sửa đổi để mở rộng cụ thể đối tượng Session để nó có tùy chọn nhận "an toàn" như Session.StringIfNull ("SessionVar") và Session ["SessionVar"] = "myval"; Nó phá vỡ sự đơn giản của việc truy cập biến thông qua Session ["SessionVar"], nhưng nó là mã sạch và vẫn cho phép xác thực if null hoặc if string nếu bạn cần.


1

Kiểm tra không có gì / Null là một cách để làm điều đó.

Đối phó với các loại đối tượng không phải là cách để đi. Khai báo một kiểu nghiêm ngặt và cố gắng ép kiểu đối tượng thành đúng kiểu. (Và sử dụng gợi ý cast hoặc Convert)

 private const string SESSION_VAR = "myString";
 string sSession;
 if (Session[SESSION_VAR] != null)
 {
     sSession = (string)Session[SESSION_VAR];
 }
 else
 {
     sSession = "set this";
     Session[SESSION_VAR] = sSession;
 }

Xin lỗi vì bất kỳ vi phạm cú pháp nào, tôi là VB'er hàng ngày


1

Thông thường, tôi tạo SessionProxy với các thuộc tính được đánh mạnh cho các mục trong phiên. Mã truy cập các thuộc tính này sẽ kiểm tra tính rỗng và thực hiện truyền sang loại thích hợp. Điều tốt đẹp về điều này là tất cả các mục liên quan đến phiên của tôi được lưu giữ ở một nơi. Tôi không phải lo lắng về việc sử dụng các khóa khác nhau trong các phần khác nhau của mã (và tự hỏi tại sao nó không hoạt động). Và với sự phụ thuộc và chế nhạo, tôi hoàn toàn có thể kiểm tra nó bằng các bài kiểm tra đơn vị. Nếu tuân theo các nguyên tắc DRY và cũng cho phép tôi xác định các giá trị mặc định hợp lý.

public class SessionProxy
{
    private HttpSessionState session; // use dependency injection for testability
    public SessionProxy( HttpSessionState session )
    {
       this.session = session;  //might need to throw an exception here if session is null
    }

    public DateTime LastUpdate
    {
       get { return this.session["LastUpdate"] != null
                         ? (DateTime)this.session["LastUpdate"] 
                         : DateTime.MinValue; }
       set { this.session["LastUpdate"] = value; }
    }

    public string UserLastName
    {
       get { return (string)this.session["UserLastName"]; }
       set { this.session["UserLastName"] = value; }
    }
}

1

Tôi cũng thích bọc các biến phiên trong thuộc tính. Các setters ở đây là tầm thường, nhưng tôi thích viết các phương thức get để chúng chỉ có một điểm thoát. Để làm điều đó, tôi thường kiểm tra null và đặt nó thành giá trị mặc định trước khi trả về giá trị của biến phiên. Một cái gì đó như thế này:

string Name
{
   get 
   {
       if(Session["Name"] == Null)
           Session["Name"] = "Default value";
       return (string)Session["Name"];
   }
   set { Session["Name"] = value; }
}

}


1

Phương thức này cũng không giả định rằng đối tượng trong biến Session là một chuỗi

if((Session["MySessionVariable"] ?? "").ToString() != "")
    //More code for the Code God

Vì vậy, về cơ bản thay thế biến null bằng một chuỗi rỗng trước khi chuyển đổi nó thành một chuỗi vì ToStringlà một phần của Objectlớp


0

Nếu bạn biết đó là một chuỗi, bạn có thể sử dụng hàm String.IsEmptyOrNull ().


0

Bạn đang sử dụng .NET 3.5? Tạo một phương thức mở rộng IsNull:

public static bool IsNull(this object input)
{
    input == null ? return true : return false;
}

public void Main()
{
   object x = new object();
   if(x.IsNull)
   {
      //do your thing
   }
}

1
Điều đó có thể được viết: public static bool Is (đầu vào đối tượng này) {return input == null; }
James Curran

Bạn nên cẩn thận với các phương pháp mở rộng.
Chris Pietschmann 24/10/08

1
Tại sao tôi nên cẩn thận với các phương pháp mở rộng?
Michael Kniskern

tại sao bạn không đơn giản sử dụng x == null hoặc x! = null?
Benoit

0

bằng cách này, nó có thể được kiểm tra xem có một chìa khóa như vậy không

if (Session.Dictionary.ContainsKey("Sessionkey"))  --> return Bool
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.