确定会话变量在C#中为null或为空的最佳方法是什么?


79

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

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

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

Answers:


114

遵循别人所说的。我倾向于分为两层:

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

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而不是为呈现给Users的变量设置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中时,请始终确保对象可序列化。在Web场上尝试使用泛型来保存对象可能太容易了,而且它日趋繁荣。我在工作时部署在Web场上,因此在核心层的代码中添加了检查,以查看对象是否可序列化,这是封装Session Getter和Setters的另一个好处:)


好办法!我已经使用类似的东西很长时间了,但是没有合并泛型。这样可以避免不同的开发人员创建类似的Session变量带来的许多问题。
DOK

如果“抛出新的ApplicationException(“没有Http上下文,没有要获取的会话!”),我该怎么办?执行?,我对自动实现的属性感到困惑,在代码的一半中,发生时我可能会得到异常。
Marztres

好的方法。我在C#类库中实现此功能时遇到问题。我无法解析对HttpSessionState/的引用HttpContext。您是否必须在DLL中安装MVC库以导入适当的名称空间?
seebiscuit

18

那就是你要做的。但是,可以使用较短的语法。

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

这就是说,如果会话变量为null,则将sSession设置为“ set this”


1
您不能这样做... Session [“ variable”]是一个对象,然后编译器会将其转换为String,因为sSession是String,如果Session [“ variable”]不存在,则会引发异常!
balexandre

你是绝对正确的。如果Session不为null,我更新了代码以强制转换字符串。
伊利

14

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

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

那么您可以将其视为字符串。

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

这就是我的工作,这使得在应用程序中访问会话变量变得更加容易。我倾向于为数据创建类,并为所有空检查工作做一些静态属性。
罗伯·库珀

如果要在会话中存储一个对象而不是一个字符串怎么办?
亚伦·帕尔默

1
见我的回答,使用泛型在存储其他对象时启用类型安全性。
罗伯·库珀

?对不起,是“会话(“”部分正确的我得到的错误。
耶稣萨莫拉

它将在VB中。:)更改为方括号。
格雷格·奥格尔2014年

8

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

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

我的概念是您应该将Session变量放入局部变量中,然后适当地处理它们。始终假定您的Session变量可以为null,并且永远不要将其转换为非null类型。

如果需要非空类型变量,则可以使用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;
}

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或是否需要字符串。


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


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

1

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

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

}


1

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

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

因此基本上将空变量替换为空字符串,然后再将其转换为字符串,因为它ToStringObject类的一部分


0

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


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

1
可以这样写:public static bool Is(此对象输入){return input == null; }
James Curran

您应该谨慎使用扩展方法。
克里斯·彼得施曼

1
为什么我要谨慎使用扩展方法?
Michael Kniskern

为什么不简单使用x == null或x!= null?
Benoit 2015年

0

这样就可以检查是否有这样的密钥

if (Session.Dictionary.ContainsKey("Sessionkey"))  --> return Bool
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.