Recently Mark Arend and I were helping out a co-worker setup Session State on SharePoint 2010 and he pointed out something very important; while I was providing the means to enable the “State Service” I was not providing the method to turn on ASP.Net session state. At first I was not clear on the distinction however once I read his email for the 3rd time after my second cup of coffee I finally got it..while I was using New-SPStateServiceDatabase to setup the State Service DB he was suggesting to use Enable-SPSessionStateService. Yea it looks pretty clear now that these are two very different commands however in my stupor after working on User Profile Sync issues over the past couple of days these were equal in my feeble mind.
So what’s the difference? The State Service is used by InfoPath Forms Services (IPFS), the Chart Web Part, and when the user is not running Silverlight Visio Services will use this too. The ASP.Net session state is used within aspx pages, controls, Web Parts, etc to store user/session scoped state such as when you make a call to Page.Session.Add(“Key”, new object()); As developers, we have access to the Asp.Net Session state only while the State Service is reserved for the Office Server applications mentioned previously.
How to Enable SharePoint’s State Service
Out of the box (OOTB) you may find you receive an error stating Session State is not enabled. This error is referring to the SharePoint State Service which needs to be enabled. If you use the Configuration Wizard you will see this choice present along with numerous other services however if you choose to not enable it through the Configuration Wizard you will need to use PowerShell. For some reason this service does not appear as on option on the “New” ribbon button within the Service Application. In my previous blog post I provided a PowerShell script which setup the State Service. While there are quite a few verbs to this commandlet you only really need the “New” to install/setup this type of session state.
Here is a sample command which installs the State Service:
#### ##Install new State Service #### New-SPStateServiceDatabase -Name "StateSvcDB" -DatabaseServer "db1" | New-SPStateServiceApplication -Name "State Svc" | New-SPStateServiceApplicationProxy -Name "State Svc Proxy" -DefaultProxyGroup
How to Enable ASP.Net Session State
The only way to install ASP.Net Session State is through PowerShell using *-SPSessionStateService. [Enable | Disable | Get | Set]-SPSessionStateService
Using this example I was able to install the ASP.Net Session State on my development farm. Note you must pass a database name which does not include any spaces. If you happen to do this you will receive an error and you may notice additional SQL Server Agent Jobs (which I will discuss later) which are created each time you try to pass off a DB name with a space (jeez you think I actually did this or what).
#### ## Enable session state #### Enable-SPSessionStateService -DatabaseName "ASPNet_Session_State" -DatabaseServer "db1" -SessionTimeout 30
Once enabled each web.config file is modified by adding the System.Web.SessionState.SessionStateModule to the list of Http modules. In addition a new sessionState element is added similar to the following:
<!-- web.config settings --> <sessionState mode="SQLServer" timeout="30" allowCustomSqlDatabase="true" sqlConnectionString="Data Source=db1;Initial Catalog=ASPNet_Session_State;Integrated Security=True;Enlist=False;Connect Timeout=15" />
Notice I said “each” web.config file is modified, that is, all root web.config files for all Web Applications are modified, for example see the following image. When new Web Applications are added later they too will receive this web.config modification when provisioned.
Now this does not mean ASP.Net Session state is available on any web application out the gate. An administrator would have to enable session state at each web application by locating the “pages” element such as this: <pages enableSessionState=”false” and changing the enableSessionState to true. After making this change Session state is now available to be used.
When using Visual Studio 2010 to create SharePoint projects you can create aspx pages using designers such as the Application Page designer. These designers create pages with a <%@ Page tag which does not supply an EnableSessionState attribute, the default for this attribute is “true” so for almost all cases you have just enabled session state for all your pages by making the change above. SharePoint 2010 uses the OOTB ASP.Net Session State provider and Session State HttpModule. This means State is binary de-serialized once at the beginning of a page request and serialized back once the request is complete. This happens on any page where 1)session state has been enabled on the farm, 2) enableSessionState is true on the web application, 3) there is a valid session state cookie being sent from the client, 4) the Page does not include an EnableSessionState attribute or the attribute is set to true.
If you decide to use session state it is prudent to ensure a) its enabled (Page.Session != null) and b) you explicitly set enableSessionState to “false” where you don’t need session state or “ReadOnly” where you only need a read only copy of the session state were you do not plan to write back to (note you can do Session.Add(..) or Session[key]=”” within a page with ReadOnly set, the changes just will not be persisted). When “true” or not present two round trips are made to the Session State DB for each page request. Setting this value to “false” eliminates these round trips while setting it to “ReadOnly” means we only fetch the session state from the DB on page request and throw it away when the request completes meaning you can cut the number of round trips in half.
Scale is important here as there is only one Session State DB per farm to be used for all Web Applications, so investigate other means of storing state before enabling this feature. Session State is track via a cookie sent back to the browser when session state is stored for the client, this occurs for each web application which uses session state. So if you have my.contoso.com and intranet.contoso.com which both happen to use session state, both are on the same farm, they will use different session state cookies and different session state objects stored in the same session DB. Since session is stored and shared within a Web Application operations performed on the session state such as Session.Clear(), Session.Abandon(), etc can potentially impact other applications, pages, or sites which use session state. Keep this in mind if you have developers complaining about losing session state – its probably not SQL or ASP.net’s fault, its probably someone trying to be a good citizen and clearing out the session state.
Session Expiry is handled by a SQL Server Agent Job which is installed when you enable the service. This job runs once a minute cleaning up any expired sessions. It’s important your SQL Server Agent service is running. This was not always the case for MOSS 2007 and an important change here; otherwise your ASP.Net session state will not be cleaned up meaning your database will grow, and grow, and…you get it.