79

在 ASP.NET C# 中检查会话变量是否存在的最佳方法是什么?

我喜欢将String.IsNullOrEmpty()作品用于字符串,并想知道是否有类似的方法用于Session. 目前我知道的唯一方法是:

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

12 回答 12

115

跟随其他人所说的。我倾向于有两层:

核心层。这是在几乎所有 Web 应用程序项目中添加的 DLL 中。在这个我有一个 SessionVars 类,它为 Session 状态获取器/设置器执行 grunt 工作。它包含如下代码:

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;
    }
}

注意获取任何类型的泛型。

然后,我还为特定类型添加 Getters/Setters,尤其是字符串,因为我经常更喜欢使用 string.Empty 而不是 null 来处理呈现给用户的变量。

例如:

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);
}

等等...

然后我创建包装器将其抽象出来并将其带到应用程序模型中。例如,如果我们有客户详细信息:

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

你明白吗?:)

注意:在为已接受的答案添加评论时想到了。使用状态服务器时,在将对象存储在 Session 中时,始终确保对象是可序列化的。在网络农场上尝试使用泛型保存对象非常容易,而且它会蓬勃发展。我在工作中部署在网络农场上,因此在核心层中对我的代码添加了检查,以查看对象是否可序列化,这是封装 Session Getter 和 Setter 的另一个好处:)

于 2008-10-24T20:25:41.873 回答
18

这几乎就是你的做法。但是,您可以使用更短的语法。

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

这就是说如果会话变量为空,则将 sSession 设置为“设置此”

于 2008-10-24T19:37:44.047 回答
14

将它包装在属性中可能会使事情变得更加优雅。

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

然后你可以把它当作一个字符串。

if( String.IsNullOrEmpty( MySessionVar ) )
{
   // do something
}
于 2008-10-24T19:59:42.007 回答
8

c# 3.0 中的“as”表示法非常干净。由于所有会话变量都是可为空的对象,因此您可以获取该值并将其放入您自己的类型变量中,而不必担心引发异常。大多数对象都可以这样处理。

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

我的概念是您应该将 Session 变量拉入局部变量,然后适当地处理它们。始终假设您的 Session 变量可以为空,并且永远不会将它们转换为不可为空的类型。

如果您需要一个不可为空的类型变量,则可以使用 TryParse 来获得它。

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;
}
于 2008-10-24T21:00:24.487 回答
2

在我看来,最简单且清晰易读的方法是:

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

它可能不是最有效的方法,因为即使在默认情况下它也会转换默认字符串值(将字符串转换为字符串),但如果您将其作为标准编码实践,您会发现它适用于所有数据类型,并且易于阅读。

例如(一个完全虚假的例子,但它说明了这一点):

 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);

我喜欢泛型选项,但它似乎有点矫枉过正,除非你希望到处都需要它。可以修改扩展方法以专门扩展 Session 对象,使其具有“安全”获取选项,例如 Session.StringIfNull("SessionVar") 和 Session["SessionVar"] = "myval"; 它打破了通过 Session["SessionVar"] 访问变量的简单性,但它是干净的代码,并且仍然允许验证是否为 null 或是否为字符串(如果需要)。

于 2011-08-23T01:30:45.583 回答
2

此方法也不假定 Session 变量中的对象是字符串

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

所以基本上在将空变量转换为字符串之前用空字符串替换它,因为它ToStringObject类的一部分

于 2016-05-17T13:35:35.780 回答
1

检查无/空是这样做的方法。

处理对象类型不是要走的路。声明一个严格类型并尝试将对象转换为正确的类型。(并使用强制转换提示或转换)

 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;
 }

对不起任何语法违规,我是一个日常的VB'er

于 2008-10-24T19:39:09.597 回答
1

通常,我为会话中的项目创建具有强类型属性的 SessionProxy。访问这些属性的代码检查是否为空,并将转换为正确的类型。这样做的好处是我所有与会话相关的项目都保存在一个地方。我不必担心在代码的不同部分使用不同的键(并且想知道为什么它不起作用)。通过依赖注入和模拟,我可以通过单元测试对其进行全面测试。如果遵循 DRY 原则,也让我定义合理的默认值。

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; }
    }
}
于 2008-10-24T20:23:24.547 回答
1

我还喜欢将会话变量包装在属性中。这里的设置器是微不足道的,但我喜欢编写 get 方法,因此它们只有一个退出点。为此,我通常在返回会话变量的值之前检查 null 并将其设置为默认值。像这样的东西:

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

}

于 2008-10-25T07:26:05.833 回答
1

通过这种方式可以检查这样的密钥是否可用

if (Session.Dictionary.ContainsKey("Sessionkey"))  --> return Bool
于 2018-10-08T12:38:54.253 回答
0

您使用的是 .NET 3.5 吗?创建一个 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
   }
}
于 2008-10-24T19:47:56.507 回答
0

如果您知道它是一个字符串,则可以使用 String.IsEmptyOrNull() 函数。

于 2008-10-24T19:51:42.677 回答