2010-03-09 54 views
2

我正在寻找一个已经出现在我公司的不少项目中的设计模式。它在历史上的功能是正确的,但是我听到一些其他开发者认为使用这种模式有可能会话损坏。我正在从Stack Overflow的其他.NET开发人员那里获得洞察力。ASP.NET会话访问技术是多用户安全的吗?

基本上,有一个类 - 通常是static或Singleton模式,主要取决于编写它的开发人员 - 存储在App_Code中。

此类封装通过属性访问当前会话。所有这些特性采取以下形式:

public static class SessionHelper 
{ 
    public static string SessionValue 
    { 
     get 
     { 
      object o = HttpContext.Current.Session["sessionValueName"]; 
      if (o == null) 
      { 
       // Replace the following with code to store & retrieve 
       // a default value of the appropriate datatype. 
       o = string.Empty; 
       HttpContext.Current.Session["sessionValueName"] = o; 
      } 

      return o.ToString(); // or cast, ensure cast is valid & return. 
     } 
     set 
     { 
      HttpContext.Current.Session["sessionValueName"] = value; 
     } 
    } 

    // Other properties, strongly-typed, as above. 
} 

(这些都不是静态的,当类是一个Singleton)

我已经看到了在过去的网站的静态数据,很大程度上是因为静电问题数据被用来维持每会话状态。 (例如,我曾看到静态声明的“每用户”代码隐藏成员,而不是我的代码;我的团队是编写该混乱的公司的清理团队。)

但是,因为这只是HttpContext.Current.Session的一个静态条目,它看起来应该是安全的,因为它与Session属性中包含此类的Page类基本上没有任何区别。正如我所说的,没有其他公司曾经使用过这种模式的网站发现它有任何问题 - 包括一些非常大且活跃的用户基础。但我想要得到一个全新的视角。

是否有潜在的多用户问题,竞争条件或其他缺点/缺陷,其具体可能会导致会话腐败上面的图案?

回答

2

这是安全的属性添加XML文档注释记录您的会议项目。你通过一些静态属性或静态类访问它的事实是完全不相关的。这是一种语言抽象。会话提供程序负责将请求映射到其正确的会话......所以,除非在此存在错误,否则您是A-OK。

3

我使用的是非常相似的方法,因为你提出的一个,并没有发现任何问题至今。

也许有一点要关心的是硬编码的会话密钥:你永远不能肯定的是,并不是同一个密钥用于在另一个位置不同的目的。

这就是为什么我仅依靠一个键,用于“我的会议”存储在ASP.NET会话。然后,所有会话数据将作为“我的会话”对象的常规属性实现。


这里是我的方法看起来像:

public class MySession 
{ 
    // private constructor 
    private MySession() {} 

    // Gets the current session. 
    public static MySession Current 
    { 
     get 
     { 
     MySession session = 
      (MySession)HttpContext.Current.Session["__MySession__"]; 
     if (session == null) 
     { 
      session = new MySession(); 
      HttpContext.Current.Session["__MySession__"] = session; 
     } 
     return session; 
     } 
    } 

    // **** add your session properties here, e.g like this: 
    public string Property1 { get; set; } 
    public DateTime MyDate { get; set; } 
    public int LoginId { get; set; } 
} 

这个类存储在ASP.NET会话的本身一个实例,并允许您从任何一个类型安全的方式访问您的会话属性类,例如像这样:

int loginId = MySession.Current.LoginId; 

string property1 = MySession.Current.Property1; 
MySession.Current.Property1 = newValue; 

DateTime myDate = MySession.Current.MyDate; 
MySession.Current.MyDate = DateTime.Now; 

这种方法有几个优点:

  • 这样可以节省你很多的类型转换
  • 你不必在你的应用程序中使用硬编码的会话密钥(例如会议[“登录ID”]
  • 您可以通过MySession的
+0

+1,我*认为*我们通常在同一页;我不认为我清楚这是一个单独的类,而硬编码的键仅用于此类,因为所有会话访问均通过此类。我会适当地更新我的问题文本。但是,我喜欢单个物体在会话中的想法,这是新颖的。 :) – 2010-03-09 23:50:26

+1

嗯......我不太喜欢这种方法。这意味着您每次访问单个会话项目时都会收到/设置一切。这可能是一个昂贵的操作,具体取决于您的会话提供程序。 – Bryan 2010-03-10 07:29:18

+0

@Bryan:这很好!但通常我们尽量保持会话状态尽可能小,并且获得包含20个值的对象(如我的方法)或分别获得5或10个值的区别可能不大。 – M4N 2010-03-10 09:36:32