【问题标题】:Can I store session variables for each user in Global.asax file?我可以将每个用户的会话变量存储在 Global.asax 文件中吗?
【发布时间】:2011-08-31 13:17:43
【问题描述】:

我有一个 asp.net c# 应用程序。我正在使用 Web 表单身份验证。我希望用户登录或在网站上注册后在 Session 中写入他的信息,例如:

  • 用户 ID、电子邮件、姓名、电话、地址等

我也在使用 openid 身份验证。

在我看来,会话可以从母版页或 Global.asax 文件中保存。就我而言,我有 3 个不同的母版页,我想从一个地方保存和删除用户会话变量。

它还必须是安全的。无论如何,在应用程序生命周期的哪个时间点更好地存储每个用户唯一的会话变量?最佳实践

【问题讨论】:

    标签: c# asp.net webforms


    【解决方案1】:

    我会提出一些不同的建议:

    从 BasePage 继承所有页面。 在该 BasePage 中创建一个用户属性,如下所示:

     public class BasePage : System.Web.UI.Page
     {
        public WebUser CurrentUser
        {
            get 
            {
                WebUser currentUser = HttpContext.Current.Session["WHATEVERKEY"] as WebUser;
    
                if (currentUser == null)
                {
                   currentUser = new WebUser();//and do some processing
                   HttpContext.Current.Session["WHATEVERKEY"] = currentUser;
                }
                return currentUser;
            }
            set 
            { 
                HttpContext.Current.Session["WHATEVERKEY"]=value;
            }
        }
     }
    

    用户通过身份验证后,您可以简单地存储您的用户信息:

    this.Page.CurrentUser = userAuthenticated;
    

    您可以在应用程序的所有页面中访问此 CurrentUser。

    WebUser 类可能如下所示:

    [Serializable]
    public class WebUser
    {
    
       public string Name {get;set;}
       public string Email {get;set;}
       // and so on... 
    }
    

    【讨论】:

    • 设置currentUser = value;有什么意义?据我所知,该值永远不会被读取。另外,我想暗示currentUser 是一个私有的后备变量,但为了清楚起见,您可能应该明确添加它。或者,由于您从未真正使用过它,您可以将其设为局部变量。
    • @mflodin 的重点是访问从 BasePage 派生的任何页面上的 WebUser 属性。我将类型添加到 currentUser。我错过了那部分。
    • 我使用@Icarus 建议通过将其作为新的 c# web 项目添加到现有解决方案来获取 currentUser* 我正在维护包含 2 个项目;一个用 vb 和另一个 c# 编写。我在两个原始项目之间共享会话变量(AD 用户名)时遇到问题。我不确定它是否适用于用不同语言编写的两个项目,但确实如此! * 现有的 Web 应用解决方案是使用 .NET 2003 (1.1) 编写的 - 我最近使用 VS 2008 将其转换为 3.5。
    【解决方案2】:

    除非在 global.asax 中通过 HttpContext.Current 以外的其他方式访问 Session 实例,否则这将不起作用 - 因为您无法从该代码的范围内访问当前上下文. (你可以直接访问它,因为HttpApplication 暴露了一个Session,但是这方面有一些注意事项。)

    但是,您可以定义第四个母版页作为根并执行使用该会话的通用代码,然后让每个母版页都派生自这个。

    【讨论】:

      【解决方案3】:

      您可以在 Global.asax 文件中使用Application_BeginRequest 方法。

      在该方法中,您可以访问“this.Session”并做任何您想做的事情。

      【讨论】:

      • 请注意您自己的 Google 结果中的this link,显示访问此会话并不总是符合预期。
      • 这就是为什么我没有说使用 Session_End 方法:) ...但即便如此,使用 HttpContext.Current.Session 非常好。
      • 您无法从 global.asax 访问HttpContext.Current.Session
      【解决方案4】:

      你可以从你想要的其他地方做我建议你以下:

      public class User{
      
      int UserID;
      string Email;
      string Name;
      string Phone;
      string Address
      }
      
      public static class SessionData{
       static User User{
      get{
      return (User)HttpContext.Current.Session["user"];
      }
      set{
      HttpContext.Current.Session["user"] = value;
      }
       static bool  IsUserConnected{
      get{
      return HttpContext.Current.Session["user"]  != null;
      }
      }
      

      因此,如果您想要当前用户的 id,请执行 SessionData.User.UserID。

      PS:我很抱歉静态类^^

      【讨论】:

        【解决方案5】:

        我想我会覆盖Page 类并在那里添加会话管理代码,然后让每个母版页继承自定义类而不是Page

        【讨论】:

          最近更新 更多