Search code examples
asp.net-mvcasp.net-mvc-2global-asaxviewdata

How to get data to an MVC view from Global.asax


I have an MVC2 web app in which I've just implemented some session timeout code. In Global.asax, I added a Session_End handler that checks if a record is open for edit and, if so, issues a Web Service call to an external system to roll back the record in the repository, so it's not locked in an 'open for edit' state. The record is still displayed in the user's browser, because we can't push a message to the browser to close the record.

When the user next interacts with the (now timed-out) page, e.g. to refresh, cancel, save or submit it, the web app sees the user is not logged in (the session expired, so the login went with it), and redirects to the login page.

On the login page, I want to display a message explaining why the user got redirected, something like: "Your session timed out; please log in again. If you had a record open, it was rolled back to its prior status."

Question: from Global.asax, where can I store the message so the login controller or view can find it when we redirect? I can't seem to get a reference to ViewData in Global.asax. When I reference it like:

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

I get an error:

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

Is what I'm attempting possible, and I just don't know the right way to reference ViewData, or is ViewData inaccessible to Global.asax? In that case, what's my best option for setting a message from Global.asax to be displayed in a view?


Solution

  • @Val - First, you shouldn't be doing authentication that way. You should be using the pipeline and FormsAuthentication or similar. This can create security holes that can be exploited by attackers or malware bots. Second, there's no guarantee that Session_End will fire, so records can be locked indefinitely. For instance, if the worker process is recycled, no Session_End will ever get called, so you cannot rely on this mechanism to unlock resources.

    I suggest you rethink your design to not lock records for edit in this manner, and do not rely on session_end for anything of critical importance.