【问题标题】:How to stop basepage from recursivly detecting session timeout如何阻止基页递归检测会话超时
【发布时间】:2011-03-26 06:57:26
【问题描述】:

替代标题:如何在会话超时时重定向

最终解决方案:感谢:Robin Day(虽然我测试了 Ben 的解决方案,它也有效,其他两个解决方案也都是很好的解决方案)

我摆脱了我最初拥有的基本页面。

把这个放在 Global.asax 的 Session_Start 中

void Session_Start(object sender, EventArgs e) 
{
    string cookie = Request.Headers["Cookie"];
    // Code that runs when a new session is started
    if ((null != cookie) && (cookie.IndexOf("ASP.NET_SessionId") >= 0))//&& !Request.QueryString["timeout"].ToString().Equals("yes"))  
    {
        if(Request.QueryString["timeout"] == null || !Request.QueryString["timeout"].ToString().Equals("yes"))
            Response.Redirect("Default.aspx?timeout=yes");
    }
}

把这个放在 Defualt.aspx 页面上:

 if (!IsPostBack)
    {
        if (Request.QueryString["timeout"] != null && Request.QueryString["timeout"].ToString().Equals("yes"))
        {
            Response.Write("<script>" +
               "alert('Your Session has Timedout due to Inactivity');" +
               "location.href='Default.aspx';" +
               "</script>");
        }
    }

即使 Default.aspx 页面发生超时,此解决方案也有效


结束解决方案

我有一个检查会话超时的基本页面。 (这就是它所做的一切)。如果会话超时,我想重定向到主页。但是,主页也继承自此基本页面。

我不确定我是否解释得很好:

第 1 步:加载我的一个页面

第 2 步:等待超过 20 分钟(这会导致会话超时)。

第 3 步:我点击了导致回邮的内容

第 4 步:Basepage 检测超时并重定向到 default.aspx

第 5 步:加载 default.aspx 时,基本页面检测到仍然存在超时,并再次尝试重定向到 default.aspx。 第 6 步:重复第 5 步

粗体是不想要的效果...

这是基本页面代码。

using System;  
using System.Web.UI;   
public class SessionCheck : System.Web.UI.Page  
{   
public SessionCheck()  {}  

override protected void OnInit(EventArgs e)  
{  
    base.OnInit(e);  

    if (Context.Session != null)  
         {  
             //check the IsNewSession value, this will tell us if the session has been reset.  
             //IsNewSession will also let us know if the users session has timed out  
             if (Session.IsNewSession)  
             {  
                //now we know it's a new session, so we check to see if a cookie is present  
                 string cookie = Request.Headers["Cookie"];  
                 //now we determine if there is a cookie does it contains what we're looking for 
                 if ((null != cookie) && (cookie.IndexOf("ASP.NET_SessionId") >= 0))  
                 {  
                     //since it's a new session but a ASP.Net cookie exist we know  
                     //the session has expired so we need to redirect them  
                     Response.Redirect("Default.aspx?timeout=yes&success=no");  
                 }  
             }  
         }  
     }  
} 

谢谢!!!

(如果您需要进一步说明,请询问)

注意:我知道如果我重定向到一个不从该基本页面继承的页面,它将解决问题。但我不喜欢这种解决方案。

【问题讨论】:

    标签: asp.net session redirect recursion timeout


    【解决方案1】:

    创建一个通用的基本页面,其中包含您希望在主页和其他页面中拥有的所有内容。

    从这个你的主页和另一个基本页面(比如 SessionCheck)继承你的会话过期逻辑。除了主页之外,您的所有页面都必须从 SessionCheck 页面继承。

    public class BasePage: System.Web.UI.Page //(this contains all things shared between all pages)
    public class SessionCheck : BasePage //(your session loginc in this class)
    public class Home : BasePage 
    

    【讨论】:

    • 有点明白。您的基本说法是主页没有从进行会话检查的基本页面继承
    • 是的。最好从一个通用的基本页面继承(如果必须在主页和其他页面之间共享其他代码)
    • 是的,我想到了这个。我真的希望有一个解决方案可以检查包括主页在内的任何页面上的超时。
    • 您能否重定向到另一个仅用于显示警报的页面?在此页面中,您无需进行检查。您可以从主页继承此页面并重新覆盖 OnInit
    • 我觉得最好从Timeout.aspx调用js然后重定向
    【解决方案2】:

    在您的基本页面中放置一个属性:

    public bool IsDefault { get; set; }
    

    在默认页面的 PreInit 事件中:

    public void Default_PreInit(object sender, System.EventArgs e)
    {
        this.IsDefault = true;
    }
    

    修改您的会话检查:

    if (Context.Session != null && !this.IsDefault)
    {
        // blibbitty blah blah
    }
    

    【讨论】:

    • 如果我在一个超时的页面上然后我尝试导航到默认页面,这将不起作用
    • @kralco626 - 我不确定你的意思。此属性设置只会出现在默认页面中。究竟什么是行不通的?
    • 我是这样理解的。我在第 x 页上,20 分钟内我什么都没做。我单击指向 default.aspx 的链接。 Preinit 方法设置 this.IsDefault = true。然后basepage init 方法会看到这个并且不执行代码。
    【解决方案3】:

    下面将使用您现有的代码来解决问题,但 robin day 建议使用 global.asax 是一个更好的选择。

    if (Context.Session != null)  
         {  
             //check the IsNewSession value, this will tell us if the session has been reset.  
             //IsNewSession will also let us know if the users session has timed out  
             if (Session.IsNewSession)  
             {  
                //now we know it's a new session, so we check to see if a cookie is present  
                 string cookie = Request.Headers["Cookie"];  
                 //now we determine if there is a cookie does it contains what we're looking for 
                 if ((null != cookie) && (cookie.IndexOf("ASP.NET_SessionId") >= 0))  
                 {  
                     //since it's a new session but a ASP.Net cookie exist we know  
                     //the session has expired so we need to redirect them
                     //Only redirect if the current page is NOT Default.aspx
                     if (Request.Path.Substring(Request.Path.LastIndexOf("/")) != "/Default.aspx") 
                     {
                         Response.Redirect("Default.aspx?timeout=yes&success=no");  
                     }
                     else if (Request.QueryString["timeout"] == "yes")
                     {
                         ScriptManager.RegisterStartupScript(this, this.GetType(), "TimeOutScript", "alert('Your session timed out');", true);
                     }
                 }  
             }  
         } 
    

    编辑答案以响应下面的 cmets,因为这比添加更多 cmets 更容易:

    我没有为您提供会话超时时重定向的解决方案,您根本无法这样做,会话已超时,没有什么可重定向的。你说“我只是想知道是否有超时”,我给了你一个解决方案。没有真正的方法可以判断用户是否正在点击页面 x,因为他们的会话已超时或因为他们打开了浏览器并开始了新会话,您所知道的只是没有现有的会话。如果他们点击了需要通过身份验证才能查看的页面,那么您可以假设会话已超时,因为他们不应该从头开始点击该页面。但是您不能在主页上执行此操作,因为您无法区分在此页面上会话超时的用户和第一次访问该页面的用户。我已经更新了代码,以便对于 Default.aspx 以外的每个页面,它都会重定向,如果由于会话超时而重定向到 Default.aspx,它将弹出一个 javascript 警报。

    【讨论】:

    • 是的,看起来这可能是解决方案。另外两个人也提到过……我只是觉得这不是最好的解决方案,因为如果我想知道我在 default.aspx 页面上发生的超时怎么办?
    • 当会话超时时,您无法真正知道用户上次访问的页面,而不执行诸如将每个用户最后访问的页面存储在数据库中并在每次访问新页面时更新它.如果页面是 Default.aspx,您只能判断正在访问的页面是否正在开始一个新会话,如果您想要执行除重定向之外的其他操作,那么只需在我添加的 if 语句中添加一个 else 并将您的代码放在那里。
    • 我不在乎超时发生在哪个页面,我只想知道是否有超时(在任何页面上,包括 default.aspx 页面)
    • 如果你向 Global ASAX 添加一个方法protected void Session_End(object sender, EventArgs e),它将在会话到期时执行,你可以在那里做一些事情。这将在会话结束时触发,而不仅仅是在超时时触发,例如如果您有一个注销进程会终止会话,那么它也会触发。
    • 不要注销,因为没有登录。站点根据您的 Windows 登录名自动进行身份验证。这是公司网络上的内部站点...所以可以工作...我可以从该方法调用 javascript 模型警报吗?
    【解决方案4】:

    我们有类似的情况。我们首先检查是否有 Session Timeout 并且在其中我们只在当前页面不是默认登录页面时重定向。

    【讨论】:

    • 如果我在主页上并且会话超时,我想要重定向,因为我希望查询字符串说 timeout = true。虽然也许这并不重要。如果我不知道默认页面上的超时,我想这没什么大不了的......
    • 对我们来说,这是最简单的解决方案,但我们发现对于这个小问题来说,其他一切都是多余的。所以我们这样做了。如果它是同一个页面,我们只是没有重定向。
    • 只需定义您在哪里进行重定向和不想重定向的标准,然后采取相应的行动。例如。如果您在重定向时设置了查询字符串 timeout = true 并且您不希望它进入无限循环,那么如果查询字符串已经超时则不要重定向 = true
    • 好吧,andrea 在那个答案的 cmets 中提到了这一点,但我们认为在 init 方法中查询字符串是不可访问的......
    • 但您可以设置一个标志来确定是否应该执行重定向。从 Page_Load 中,您可以检查标志并有条件地重定向。
    【解决方案5】:

    您可以在Global.asax 中使用事件Session_OnStart 吗?

    每当新会话开始时都会触发一次。您可以在那里进行重定向。

    我猜的关键是,如果你还没有在主页上,你只会重定向到主页。您可以通过检查 Request 对象中的 URL 来做到这一点。

    【讨论】:

    • 我非常喜欢第一个想法!你能进一步解释一下(idk Global.asax 是什么......)但是如果我在主页上并且会话超时我想要重定向,因为我希望查询字符串说 timeout = true。
    • 这是一个 ASP.Net Web 应用程序项目吗?在项目的根目录中应该有一个名为Global.asax 的文件。这应该有一个相应的代码隐藏文件。如果它不存在,那么您可以右键单击该项目并选择 Add New Item 并选择 Global Application Class
    • 甜蜜。我得到了 global.asax 文件。但是,如果我在 session_start 事件上做一些事情,那么当我第一次加载站点并创建一个新会话时也不会执行?
    • 您可以像以前一样进行 cookie 检查,以检查是否存在预先存在的会话。使用这个事件的关键是它只会触发一次。因此,您所做的任何重定向都不会导致它重新触发。
    • 我在 Session_End 中进行重定向时出错。我读到不可能在 session_end 中进行重定向:forums.asp.net/p/1137344/1834495.aspx(第二篇文章)
    猜你喜欢
    • 1970-01-01
    • 2016-01-21
    • 2010-11-26
    • 2010-12-23
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 2012-01-03
    • 2018-12-13
    相关资源
    最近更新 更多