views:

694

answers:

1

I'm basically using the AccountController from the ASP.NET MVC samples. It uses FormsAuthentication to handle the user login. Just to be sure, here is the code to handle user login:

    public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
    {
      if (!ValidateLogOn(userName, password))
      {
        return View();
      }

      FormsAuth.SignIn(userName, rememberMe);


      //Session["userId"] = 1;


      if (!String.IsNullOrEmpty(returnUrl))
      {
        return Redirect(returnUrl);
      }
      else
      {
        return RedirectToAction("Index", "Home");
      }
    }

As you can see from the commented line, I would like to set a Session variable in this method. However, I figured that it is not the most elegant way of setting a Session variable directly in the controller. It's also inconvenient when unit testing this method (although I could mock it, sure, but still).

So, I figured, I create a custom ActionFilterAttribute that runs after this login routine. If login is succesful, set the session variable in this custom attribute. The code for this is:

  public class SetSessionAttribute : ActionFilterAttribute
  {
    public override void OnResultExecuted(ResultExecutedContext resultContext)
    {      
      if (resultContext.HttpContext.User.Identity.IsAuthenticated)
      {
        resultContext.HttpContext.Session["userId"] = 1;
      }

      base.OnResultExecuted(resultContext);
    }
  }

The problem is that User.Identity.IsAuthenticated always returns false until the next "page load". I'm overriding OnResultExecuted as I gather that it is the last method to be called in the page lifecycle, but no luck. I also tried OnActionExecuting, OnActionExecuted and OnResultExecuting, but it is always false.

Is there an elegant solution around this? Or should I give up and set the session variable in the controller directly?

A: 

I had a similar problem with log out because User.Identity.IsAuthenticated was true until next page request but I needed a way to know if user is really finished work with an application.

I think you should set Session or ViewData variable in controller or pass it to another controller via routeValues.

Alexander Prokofyev
Thanks for the reply. Yes, I could set the session in the controller but that's what I tried to avoid. I still hope there is a viable alternative to it.
Razzie