【问题标题】:Redirect to specific page after session expires (MVC4)会话到期后重定向到特定页面(MVC4)
【发布时间】:2014-08-21 10:01:26
【问题描述】:

C# MVC4 项目:我想在会话到期时重定向到特定页面。

经过一番研究,我将以下代码添加到我项目中的Global.asax

protected void Session_End(object sender, EventArgs e)
{
     Response.Redirect("Home/Index");
}

当会话过期时,它会在Response.Redirect("Home/Index"); 行抛出异常,说The response is not available in this context

这里有什么问题?

【问题讨论】:

  • 你正在使用formsauthentication..???
  • @Exception,我不确定,但我不这么认为
  • 没有人解释为什么会这样。与 global.asax 中的许多其他事件不同,Session_End 事件不会在当前请求的上下文中发生 - 它是在正常运行时间之外发送到应用程序的偶数 - 因此您不能发出重定向要求。通常,此事件用于允许应用程序从刚刚结束的会话中清理资源。在请求期间很难发生这种情况,因为请求所做的第一件事就是激活会话。

标签: asp.net-mvc-4 session session-timeout


【解决方案1】:

MVC 中最简单的方法是 在 Session Expire 的情况下,您必须在每个操作中检查其会话,如果它为空,则重定向到索引页面。

为此,您可以制作如下所示的自定义属性:-

这是覆盖 ActionFilterAttribute 的类。

public class SessionExpireAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContext ctx = HttpContext.Current;
            // check  sessions here
            if( HttpContext.Current.Session["username"] == null ) 
            {
               filterContext.Result = new RedirectResult("~/Home/Index");
               return;
            }
            base.OnActionExecuting(filterContext);
        }
    }

然后在行动中添加这个属性,如图所示:

[SessionExpire]
public ActionResult Index()
{
     return Index();
}

或者只添加一次属性:

[SessionExpire]
public class HomeController : Controller
{
  public ActionResult Index()
  {
     return Index();
  }
}

【讨论】:

  • 如果您需要在任何地方进行检查,只需将其添加到您的全局过滤器列表中:GlobalFilters.Filters.Add(new SessionExpireFilterAttribute()); in Global.asax.cs。无需添加到每个操作。
  • @chiapa 有两种方式,一种是 Exception 发布的,一种是我向您展示的,我认为 mvc 中没有其他方式
  • @EhsanSajjad...是的..但是在您的代码中,我们必须更改基本控制器才能检查会话..我认为制作自定义过滤器很好,而且如果打开我们想跳过检查会话的一些操作,那么它会产生问题......
  • @EhsanSajjad 和例外,这是一个很好的讨论,我相信这个问题需要更好的解决方案。我的疑问是,难道没有更好的方法了吗?
  • @Juhi..no 这是不可能的..肯定是其他地方有问题...OnActionExecuting() 方法将在每次执行之前调用,无论会话如何。
【解决方案2】:

这是 MVC 中的一些新内容。

Public class SessionAuthorizeAttribute : AuthorizeAttribute { Protected override void HandleUnauthorizeRequest( AuthorizationContext filtercontext ) { filtercontext.Result = new RedirectResult("~/Login/Index"); } }

在您的控制器上应用此过滤器后,您想要应用授权。

[SessionAuthorize] public class HomeController : Controller { // Something awesome here. }

SessionAuthorizeAttribute 的 HandleUnAuthorizeRequest 函数只会在授权失败时调用,而不是反复检查授权。

问候 MK

【讨论】:

  • 授权和会话是两个不同的东西,并且可以在不同的时间过期 - 您可以在仍然有有效会话的同时撤销您的授权,并且您可以在您的身份验证令牌之前有一个会话超时(因此授权)过期。
  • 感谢您的突出显示,但我仍然不清楚您能否提供一个示例。
  • 当然:当用户访问您的站点时,.net 可以发出会话令牌,通常有效期为 20 分钟,并在他们每次请求页面时重置。如果该用户随后登录,您将发出一个授权令牌,其到期时间可以长于或短于会话超时。如果它更长,但用户不再访问任何页面,则会话将在 20 分钟后超时,但授权令牌仍然有效,如果用户返回您的站点,他们仍然会登录(但会有一个新的会话)。
  • 您建议的过滤器只会在用户未登录并尝试访问受限页面时触发。 OP 使用的情况类似于搜索页面或类似的会话已超时并且丢失所有更改的情况,因此您需要重新开始,因为它们没有使用查询字符串
【解决方案3】:

创建这个动作过滤器类

    class SessionExpireAttribute : ActionFilterAttribute {
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.HttpContext.Session["logged"] == null)
        {
            filterContext.Result = new RedirectResult("/Account/Login");
        }
        base.OnActionExecuted(filterContext);
    }

然后在你的类或方法中使用它,如下所示

[SessionExpireAttribute]
public class MyController : Controller
{
    ....
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多