ASP.Net会话中的持久化对象

ASP.Net会话中的持久化对象,asp.net,session,Asp.net,Session,我正在开发一个ASP.Net应用程序(intranet),它需要用户进行身份验证才能访问门户 当前,一旦成功验证,我将员工对象保存到InProc会话状态中。然后在母版页的PageLoad方法上,我检查员工的会话是否为空(null),这意味着当前请求没有经过身份验证,然后我重定向到登录页面 母版页页面加载: if (Session["Employee"] == null) Response.Redirect("~/Login.aspx"); 我还几乎在每个页面上使用员工的会话来获取有关已登录员工

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

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

母版页页面加载:

if (Session["Employee"] == null) Response.Redirect("~/Login.aspx");
我还几乎在每个页面上使用员工的会话来获取有关已登录员工或其权限级别等的详细信息

我的问题:

if (Session["Employee"] == null) Response.Redirect("~/Login.aspx");
  • 上述技术是否适合处理此类场景
  • 有时会话状态在服务器上被回收(丢失),因此,如果我在会话为null时在任何chlid页面的PageLoad中调用会话状态,它将引发异常,因为检查会话存在性的母版页onLoad方法仅在子页onLoad方法之后运行。如何以及在何处检查统一位置中是否存在会话?因为我不想每次访问会话状态时都检查会话是否存在
  • 会话结束后是否可以触发方法?我在Global.asax中尝试了Session_End,但它不允许我调用任何方法或重定向到页面
  • 谢谢,

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

    • 如何以及在何处检查统一位置中是否存在会话
    我建议将用户跟踪的会话部分抽象为应用程序中的公共对象。在该对象中,您将检查会话是否为null,检查用户是否登录,相应地作出响应,等等。然后所有页面(子页面和主页面)都应该使用该对象

    这有两个好处:

  • 您只需在一个地方编写会话逻辑。因此,您不会在整个应用程序中不断地为会话编写条件。应用程序的其余部分只调用公共对象上的方法
  • 如果您以后想将用户跟踪从会话移动到其他对象(例如,数据库……我过去使用过RavenDB和MongoDB等工具来跟踪瞬态web应用程序数据,效果很好),您只需更改一个类。应用程序的其余部分仍然只使用该公共对象
  • 例如,该类可以有如下内容:

    public static string GetCurrentUsername()
    {
        if (Session["Employee"] == null)
            throw new SomeKindOfAuthenticationException();
        return ((EmployeeObject)Session["Employee"]).Username;
    }
    
    然后在整个应用程序中,只需将用户跟踪对象调用到
    GetCurrentUsername
    。在
    Application\u Error
    中,您可以通过重定向到登录页面来处理身份验证异常。(对于未经身份验证的用户,这通常被认为是比在上述方法中返回空字符串更好的做法。在整个应用程序中,必须不断检查空字符串,而异常处理可以在单个位置进行。如果您需要特定页面,则不需要在他的情况下,而不是只是不显示一些东西,包装在异常处理本地到该页面的调用,并相应地处理它。)

    当然,考虑到这主要是一个高级设计推测,我并不是指我面前的实际实现。可能是
    静态
    会导致
    会话出现问题
    ?也许您需要将其传递给
    会话
    ?这个类应该存储在哪里?您还应该执行哪些其他错误检查?等等

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

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

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

    上述技术是否适合处理此类场景

    没有

    如何以及在何处检查统一位置中是否存在会话

    您可以将会话相关逻辑添加到基页中 这次讨论会对你有帮助


    您可以在所有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"]);
            }
        }
    
    我还几乎在每页都使用员工的会话来获取一些信息 有关已登录员工或其权限级别等的详细信息



    谢谢你的回答,我会阅读更多关于基类的内容,我认为这会很有用。谢谢David的详细回答,我已经相应地修改了代码,我制作了一个静态类,就像你的示例代码一样,但是