2011-11-18 37 views
0

我有一个MVC2 web应用程序,其中我刚刚实现了一些会话超时代码。在Global.asax中,我添加了一个Session_End处理程序,该处理程序检查记录是否打开进行编辑,如果是,则向外部系统发出Web服务调用以回滚存储库中的记录,以便它不锁定在“用于编辑'状态。记录仍然显示在用户的浏览器中,因为我们无法将消息推送到浏览器来关闭记录。当用户接下来与(现在超时)页面交互时,例如,要刷新,取消,保存或提交,Web应用程序会看到用户未登录(会话已过期,因此登录名随之一起),然后重定向到登录页面。如何从Global.asax获取数据到MVC视图

在登录页面上,我想显示一条消息,解释用户重定向的原因,如下所示:“您的会话超时;请重新登录;如果您有记录打开,则会恢复到先前的状态状态。”

问题:Global.asax,我可以在哪里存储消息,以便登录控制器或视图可以在我们重定向时找到它?我似乎无法在Global.asax中获得对ViewData的参考。当我引用它想:

System.Web.Mvc.ViewPage<My...LoginViewModel>.ViewData["ErrorMessage"] = "Your session timed out..." 

我得到一个错误:

An object reference is required for the non-static field, method, or property 'System.Web.Mvc.ViewPage<My...LoginViewModel>.ViewData.get' 

就是我试图可能的,我只是不知道引用ViewData正确的方式,或者是ViewData无法访问Global.asax?在这种情况下,将Global.asax的消息设置为在视图中显示的最佳选择是什么?

+0

它为什么需要在Global.asax中? – SLaks

+0

我不认为你的解决方案是可能的。您如何知道某条消息是针对特定用户的?由于它们没有有效的会话,它们是不是被FormsAuthentication重定向到登录页面? – Dallas

+0

@SLaks,AFAIK Session_End处理程序需要在Global.asax中,因为它是由单独的工作进程触发的,而不是我的主应用程序的进程,所以我无法在我的应用程序类中捕获它。我错了吗? – Val

回答

3

@Val - 首先,你不应该这样做认证。您应该使用管道和FormsAuthentication或类似的。这可能会产生可被攻击者或恶意软件机器人利用的安全漏洞。其次,不能保证Session_End会触发,所以记录可以无限期地锁定。例如,如果工作进程被回收,则Session_End将永远不会被调用,所以您不能依赖此机制来解锁资源。

我建议你重新考虑你的设计,不要以这种方式锁定记录进行编辑,也不要依赖session_end来处理任何重要的事情。

+0

对不起,我的评论不清楚。我们确实拥有Forms Auth loginUrl,但我们也为用户签入控制器,因此始终优先;到目前为止,我还没有看到管道做重定向。您关于Session_End不可靠的观点很好。这并不意味着是一个防弹功能,但是当用户将记录保留在夜间进行编辑时,会减少记录锁定的问题。改变我们的记录锁定语义可能是我们明年重写MVC3(4?)的一种选择,但目前还没有。 – Val

+0

@Val - Forms Auth将优先于您在页面中执行的任何操作,因为如果FormsAuth Cookie过期,页面中的代码将永远不会执行。如果您手动重定向用户,那么只需添加一个查询字符串,表明它来自会话超时。也就是说,在你做重定向的页面中(我假设你正在检查一个有效的会话,如果没有重定向),用一条消息向你的登录页面发送一个参数。 –

+0

@MM,不知道这是否会工作。我的页面已打开,但会话超时。我点击一个链接GET或POST到控制器。控制器检查会话,发现它是无效的,并重定向到登录。我没有看到我的控制器如何知道记录的状态 - 它需要提前知道用户打开编辑,才能传递正确的错误信息。 – Val

相关问题