"Dig within. Within is the wellspring of Good; and it is always ready to bubble up, if you just dig."
-- Marcus Aurelius


using the structuretoobig StateManager

There are a number of ways to use the StructureTooBig StateManager. The easiest way is to add a reference to the StructureTooBig.StateManager.dll. Under your project, right click the references tab and select "Add Reference." Then simply navigate to the bin folder and select the StructureTooBig.StateManager.dll file.

In the code file (such as a code behind or within the ASPX page directly), add the following C# using statement to make our code a little less verbose:

using StructureTooBig.StateManager;

If you're using VB.NET, use the Imports command instead.

So let's start with a very basic example. Assuming we've got a Page_Load handler, we can add some code like so:

private void Page_Load(object sender, System.EventArgs e)
{
       Response.Write("User's Machine Guid: ");
       Response.Write(State.Current.MachineGuid.ToString());
       Response.Write("<br>");
       Response.Write("User's Session Guid: ");
       Response.Write(State.Current.SessionGuid.ToString());
}

The State object cannot be instantiated directly. Rather, access is always done through the CurrentState property. There's a host of properties -- such as MachineGuid and SessionGuid -- that allow you to access items in a strongly typed and intellisense friendly way. In this case, the MachineGuid property is a Guid that (unless the user deletes their cookies) will always remain the same. The SessionGuid property is Guid that uniquely identifies the session. You can test this by closing the browser, and navigating back to the page in a new browser window. The MachineGuid should remain the same and the SessionGuid should now be different.

If you need to add objects at runtime, the State object has an indexer (like the built in session state). In the following example, nothing will be written on the first request. When the page is requested again in the same session, you should see "myvalue" written to the page:

if (State.Current["mykey"] != null)
{
       Response.Write(State.Current["mykey"].ToString());
}
State.Current["mykey"] = "myvalue";

If it's more convenient, you can also pull a reference to the StateManager object from the HttpContext directly. Here's an example of how to do that:

State myState = HttpContext.Current.Items["State"] as State;
Response.Write("Your session Guid: " + myState.SessionGuid.ToString());

This should be enough to get you off the ground. Now let's have a bit more fun by editing the module directly. There are several properties already built into the module, but it's easy to add new ones. First, let's look at the MachineGuid property in StateManager.cs:

private Guid _MachineGuid;

[Persisted]public Guid MachineGuid
{
       get { return _MachineGuid; }
       set { _MachineGuid = value; }
}

A fairly typical looking C# property with a local field. The [Persisted] attribute tells the StateManager that you want this value to live beyond the session. In other words, it gets persisted in an encrypted cookie and will be repopulated when the user comes back and initiates a new session. If you remove this attribute, the value will only be saved for the current session. Nifty, huh?

So, if you have some type you'd like to add, you have two choices: add it via the indexer (see above example), or add the property to the module (don't forget to add the local field, too). While using the indexer is easy, the latter has the advantage of intellisense support and, if you're using the value a lot, it's cleaner and more performant to add it as a property.

Let's contrive an example: suppose our site has a theme for every color (I told you this was contrived). More likely than not, we'd tag this information with some login preferences -- we'd create an entire type that contains this information. We can certainly do that, but for now, let's assume we don't want any fancy login system -- we just want people to select a color and persist that color as long as possible. So, we add a ubiquitous drop down in the corner of each page allowing the user to select a color. The StateManager is an ideal place to store this information. In StateManager.cs, we can simply add:

private System.Drawing.Color _ThemeColor = System.Drawing.Color.Blue;

[Persisted]public System.Drawing.Color ThemeColor
{
       get { return _ThemeColor; }
       set { _ThemeColor = value; }
}

The StateManager will now automatically persist the value across the current and any new sessions. If the value isn't found, it has a default of blue. In our aspx page, we may have code like this to set the value, allowing the StateManager to worry about persisting and retrieving the value:

private void ddlThemeColor_SelectedIndexChanged(object sender, System.EventArgs e)
{
       State.Current.ThemeColor =
              System.Drawing.Color.FromName(ddlThemeColor.SelectedItem.Value);
}

In the corresponding master page, user control, or whatever code controls the theme, just access the State.Current.ThemeColor property and you're good to go. This is a great way to create a customizable and anonymous site without having to resort to a lot of data persistence issues.