在ASP.Net Session中保留对象

时间:2012-03-25 12:31:54

标签: asp.net session

我正在开发一个ASP.Net应用程序(intranet),要求用户进行身份验证才能访问门户网站。

目前,我在成功通过身份验证后将 Employee对象保存到InProc会话状态。然后在Master Page的PageLoad方法中检查Employee的Session是否为空(null),这意味着当前请求未经过身份验证,然后我重定向到Login页面。

母版页PageLoad:

if (Session["Employee"] == null) Response.Redirect("~/Login.aspx");

我还在每个页面中使用员工会话来获取有关登录员工或其权限级别等的一些详细信息。

我的问题:

  1. 上述技术是否适合处理这种情况?
  2. 有时会话状态在服务器上被回收(丢失),所以如果我在会话为空时在任何 chlid页面的PageLoad中调用会话状态,它将抛出异常因为主检查会话存在的页面onLoad方法仅在子页面onLoad方法之后运行。如何以及在哪里可以在统一的地方检查会话的存在?因为每次访问会话状态时我都不想检查会话是否存在。
  3. 会话结束后是否可以触发方法?我在Global.asax中尝试了Session_End,但它不允许我调用任何方法或重定向到页面。
  4. 谢谢,

2 个答案:

答案 0 :(得分:3)

  
      
  • 上述技术是否适合处理这种情况?
  •   
当然,“好”是主观的。但这种情况应该没问题。有多种方法可以处理用户跟踪,我很好奇是否有人有任何具体的建议。

  
      
  • 我如何以及在哪里可以在统一的地方检查会话是否存在?
  •   

我建议将用户跟踪的会话部分抽象为应用程序中的公共对象。在该对象中,您将检查Session是否为空,检查用户是否已登录,相应地做出响应等。然后所有页面(子和主)应该只使用该对象。

这带来了几个好处:

  1. 您只需要在一个地方编写会话逻辑。因此,您不会在整个应用程序中不断在Session上编写条件。应用程序的其余部分只调用常见对象上的方法。
  2. 如果您以后想要将用户跟踪从Session转移到其他东西(例如数据库......我已经使用RavenDB和MongoDB之类的东西来跟踪过去的瞬态Web应用程序数据并获得了良好的结果),只需改变一个班级。应用程序的其余部分仍然继续使用该常用对象。
  3. 例如,该类可能具有以下内容:

    public static string GetCurrentUsername()
    {
        if (Session["Employee"] == null)
            throw new SomeKindOfAuthenticationException();
        return ((EmployeeObject)Session["Employee"]).Username;
    }
    

    然后在整个应用程序中,您只需将用户跟踪对象调用GetCurrentUsername即可。在Application_Error中,您将通过重定向到登录页面来处理您的身份验证例外。 (对于未经身份验证的用户,这通常被认为是比上述方法中返回空字符串更好的做法。在整个应用程序中,必须检查空字符串 ,而异常处理可能发生在一个地方。如果你需要一个特定的页面来重定向到这种情况下的登录页面而不是显示某些内容,请将该调用包装在该页面的本地异常处理中并处理它相应地。)

    当然,请考虑这主要是一个高级设计猜想,我并不是指在我面前的实际实现。可能static会导致Session出现问题?也许你需要传递Session?你应该把这个课存放在哪里?你应该做什么其他的错误检查?等等。

      
        
    • 会话结束后是否可以触发方法?
    •   

    根据我的经验,不可靠。考虑会话可以结束的所有方式。用户可以单击“注销”链接,其具有清除会话的逻辑,或者他们可以放弃浏览器,或者他们的连接可能在较长时间内失败等等.Web应用程序是被动请求/响应系统。在没有用户交互的情况下响应会话超时等同于正在进行的服务器端进程,Web应用程序不适合这样做。

    这实际上是我尝试将这种瞬态数据存储在数据库中的原因之一。这样我可以有一个单独的进程(例如Windows服务...... 设计为在没有用户请求的情况下在后台持续运行的东西)监视该数据库并相应地响应事物。在这样的设置中可以完成的一件事是一种手动的Session_End。一个单独的进程将轮询数据库中没有在X分钟内看到活动的会话(例如,通过检查活动跟踪记录上的时间戳),并通过清除相关数据和执行任何其他任务进行响应。

    在我看来,这相当干净地分离了Web应用程序(响应用户请求)和状态跟踪(维护服务器端数据)的职责。

答案 1 :(得分:0)

  

上述技术是否适合处理这种情况?

没有

  

我如何以及在哪里可以在统一的地方检查会话是否存在?

您可以将会话相关逻辑添加到基页中 这个讨论对你有用ASP.net "BasePage" class ideas


您可以在所有aspx页面中继承BasePage。以下是示例示例

public class BaseClass : System.Web.UI.Page
{
    public String UserName
    {
        get
        {
            if (HttpContext.Current.Session["UserName"] == null)
                Response.Redirect("Login.aspx");
            return Convert.ToString(HttpContext.Current.Session["UserName"]);
        }
    }
  

我也几乎在每一页都使用员工会话来获得一些   有关登录员工或其权限级别等的详细信息。

    public String FirstName
    {
       get
       {
           if (UserName == null)
              return String.Empty;
           return Convert.ToString(HttpContext.Current.Session["FirstName"]);
       }
    }
}