2012-03-25 58 views
2

我正在开发一个ASP.Net应用程序(Intranet),它要求用户进行身份验证才能访问门户。ASP.Net中的持久对象Session

目前,我将员工对象保存到InProc会话状态,一旦验证成功。然后,在主页的PageLoad方法中,我检查员工会话是否为空(空),这意味着当前请求未通过身份验证,然后我重定向到登录页面。

母版页pageLoad的:

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

我还使用了员工会议,几乎在每一个页面,以获取有关登录的员工或他的权力等层面的一些细节..

我问题:

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

谢谢

回答

3
  • 是上述技术是很好的处理这种情况?

“好”当然是主观的。但是这种情况应该没问题。有多种方式来处理用户跟踪,我很好奇,如果任何人有任何具体的建议。

  • 如何和我在哪里可以检查统一会议地点存在?

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

这带来几个好处:

  1. 你只需要编写会话逻辑在一个地方。所以你不是不断在整个应用程序的会话上写条件。应用程序的其余部分只是在一个通用对象上调用方法。
  2. 如果您稍后想要将用户跟踪从会话移至其他内容(例如数据库...例如,我已使用RavenDB和MongoDB之类的事物跟踪过去的暂时Web应用程序数据,并取得了良好的结果),那么您只需要改变一个类。应用程序的其余部分仍然继续使用该通用对象。

例如,类可以有这样的事情:

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应用程序(响应用户请求)和状态跟踪(维护服务器端数据)的责任。

+0

感谢David的详细解答,我已经相应地更改了我的代码,我制作了一个类似于您的示例代码的静态类,但是应抛出哪个异常?目前,我使用ApplicationException和一个特定的消息“Session Not Found”,然后在Application_Error方法中,我检查内部异常的消息是否与该消息相同,以便作出相应的响应。并且请注意,Employee类不在App_Code中,而是在单独的项目中,我不知道这是否会在处理异常时有所作为。 – 2012-03-25 23:22:07

+0

@OsamaMortada:当然可以抛出一个'ApplicationException'。也许是'SecurityException'?在这种情况下,你甚至可能想创建一个自定义异常并抛出。像一个'NotLoggedInException'。关于自定义异常的好处是,您也可以为其定义自己的字段。因此,在Application_Error中检查该异常类型,可以轻松从这些自定义字段中获取数据。 – David 2012-03-26 00:51:54

+0

感谢大卫,我认为SecurityException更好,因为我注意到ApplicationException总是抛出HttpException,我不得不从内部异常中得到它!我不知道为什么Application Exception总是在HttpException中变形?我也会尝试自定义异常,感谢David :) – 2012-03-26 08:41:46

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

+0

谢谢你的回答,我会阅读更多关于基类的内容,我认为它会有用。 – 2012-03-25 23:21:34