2013-07-10 76 views
0

我正在开发一个.NET MVC 4应用程序,如果在会话超时后执行某些操作,需要向用户显示“会话过期”消息。.Net MVC - 仅针对私人页面显示“会话过期”

我使用的表单身份验证具有很长的超时时间和短暂超时的会话,所以我可以知道会话是否过期或它是一个新的访问者。这是我的Web.config部分:

<authentication mode="Forms"> 
    <forms loginUrl="~/Login" timeout="10080" defaultUrl="~/Index" /> 
</authentication> 
<sessionState mode="InProc" timeout="20" /> 

正如我所说,这只是从一个会话超时区分一个新的访问者,而无需对应用程序本身。如果可以用其他方法实现相同的结果,则可以更改它。

与在Web.config中,我能做到在Global.asax如下:

protected void Session_Start(object sender, EventArgs e) 
{ 
    //if it's a new session AND the user is authenticated, then it's a session timeout 
    if (Request.IsAuthenticated) 
    { 
     if (Request.RequestContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      //... 
      //Ajax handling code 
      //... 
      //The redirect is so I can return a JsonResult with a standard object with the message 
      Response.Redirect("/GetJson?some_parameters, true); 
     } 
     else 
     { 
      Response.Redirect("/SessionExpired", true); 
     } 
    } 
} 

所有这一切的伟大工程的需要登录的网站的私人部分。问题是如果用户登录,等待会话超时,然后尝试打开一个“公共”页面,一个不需要登录,他仍然会收到“会话过期”消息。这就是我想要避免的。 “会话过期”消息应该只显示给用户,如果他试图访问需要登录的页面。

我试着在Session_Start中设置一个标志并在以后的Global.asax事件中重定向,但它不起作用,因为我有一些可变的可访问性问题。 我想尝试检查当前操作是否具有[AllowAnonymous]属性,因此我可以跳过重定向,但我无法弄清楚。 我读到的一些答案给我的印象是,我的“Session expire”逻辑应该是一个自定义属性,但我不知道这是否是正确的方法。

我的问题是,在.NET MVC 4中,只有“私人”页面才能完成“会话过期”的最佳方式是什么?

回答

1

正如你所说,理想的是使用一个属性。更确切地说,这个属性被命名为“Action Filter”。

您可以创建一个实现接口的ActionFilter,或者继承现有接口。

在你的情况,我认为最简单的方法来得到你的结果是继承AuthorizeAttribute,并覆盖其OnAuthorization方法。

在此方法中,您可以访问HttpContext作为filterContext参数的属性:filterContext.HttpContext。您可以检查会话,授权,并检查它是否是使用此属性的ajax请求。如果您需要重定向,您必须通过设置filterContext参数的属性做到这一点:

filterContext.Result = new RedirectResult("...url to redirect to..."); 

您可以使用RedirectResultRedirectToRouteResult构造函数中的任何过载。

如果您不改变Result属性,则不会发生任何特殊情况。

您可以使用此自定义属性,而不是原始授权属性。

+0

有没有一种方法可以在操作过滤器中知道会话是否仅在此请求中创建?否则...我怎么知道用户是否是新访问者或者过期会话的旧访客? – FercoCQ

+0

您可以使用充当标志的自定义cookie。你可以注册一个全局的Action Filter来处理这个cookie。如果您的自定义Cookie不存在于请求中,并且用途具有会话,则将您的Cookie设置为“新会话”。如果该请求中已存在Cookie,并且该会话处于活动状态,请将其更改为“旧会话”。如果cookie存在,但会话过期,请将其标记为“以前的会话过期”。您不必完全按照这种方式来完成,它只是您可以做的一个草图。 – JotaBe

+0

谢谢,我会在几天内尝试它,并让你知道它是如何发生的。 – FercoCQ