Using UserState in an application

There are typically 3 scenarios to use and acess the UserState object:

  • Initialize UserState when the user logs in
  • Read the UserState on each request
  • Release the UserState when the user logs out (automatic)

Initializing UserState

UserState is typically set when a user logs in when a user logs in. The UserState is set at the same time that the Form Authentication token is set.

In an MVC application this process might look like this:

var UserState = new UserState();
UserState.Email = user.Email;
UserState.UserId = user.Id.ToString();            
UserState.Name = user.Name;
UserState.IsAdmin = user.IsAdmin;

this.IssueAuthTicket(this.UserState,model.RememberMe);

In this case the IssueAuthTicket method then creates a FormsAuthTicket using standard ASP.NET logic.

Reading UserState

UserState is typically read on every request. In my ASP.NET MVC applications I tend to use a custom base controller that has a UserState property and the base controller automatically reads the UserState object on each hit if it exists.

Here's what that looks like:

public override Initialize()
{
     // Restore UserState object on each hit
     // Instance always created - if not found UserState.IsEmpty() returns .t.
     UserState = UserState.CreateFromFormsAuthTicket<UserState>();
}

There are several ways to read the user state, but the above method is the easiest as it directly reads the value from the Forms Authentication Cookie.

Alternately you can also capture the UserState encoded data directly from a string using the various static CreateFromString() overloads which are the counterpart to the ToString() method that serializes the UserState to string.

Finally logging out is simply handled by removing the FormsAuth token. As FormAuth is logged out, the UserState cookie data gets removed as well.

public ActionResult Logout()
{
    var model = CreateViewModel<LoginViewModel>();
    this.RevokeAuthTicket(model.UserState);
    this.ErrorDisplay.ShowMessage("Logged out of Classifieds");
    return View("Login",model);
}

Using UserState

Once you've logged on a user and retrieved the UserState it's up to you what to do with it.

The Westwind.Web.Mvc project contains a BaseController and BaseViewModel, both of which include UserState properties. The base controller automatically tries to the retrieve the UserState data if it exists - or otherwise creates an empty UserState object.

If using the BaseViewModel class from Westwind.Web.Mvc in combination with the BaseController::InitializeView() or BaseController::CreateView() methods automatically passes the UserState (and a few other objects) from the Controller to the View.

Once that's in place a View can easily display user information.

The most common use case is to display user information in the login/logout area of the page. Here is an example of a partial loaded form an MVC _layout.cshtml page, that uses the UserState object:

@if (!model.UserState.IsEmpty()) {
    <p>
        Hello, @Html.ActionLink(model.UserState.Name, "ChangePassword", 
             "Account", routeValues: null, 
             htmlAttributes: new { @class = "username", title = "Change password" })!
        @Html.ActionLink("Log off", "LogOff", "Account")
    </p>
} else {
    <ul>
        <li>@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink", data_dialog_title = "Registration" })</li>
        <li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink", data_dialog_title = "Identification" })</li>
    </ul>
}

While this doesn't look much different from User identity using ASP.NET membership provider, this approach avoids database access to validate the user on each hit. The credentials are cached in the forms auth ticket, and you get the ability to store more information than is typically available on a Security Principal loaded by Membership.


© West Wind Technologies, 1996-2016 • Updated: 12/19/15
Comment or report problem with topic