Return to doc.sitecore.com

Valid for Sitecore 6.0.0
SQL Server Session State Problems

How to solve a problem with a SQL server session state:

"Unable to serialize the session state in 'StateServer' and 'SQLServer'mode. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as the result non-serializable objects".

/upload/sdn5/articles 2/troubleshooting/sql server session state problems/sql server session state problems.gif 
The possible scenarios that can cause this problem are described in detail below, as well as the problem solutions to these scenarios.

Scenario 1

1) Configure a SQL server session.
2) Create an AlertMessage class inherited from Command class with the following methods:

class AlertMessage : Command
    {
        public override void Execute(CommandContext context)
        {
            Context.ClientPage.Start(this, "Pipeline");
        }     
        protected virtual void Pipeline(ClientPipelineArgs args)
        {
            if (!args.IsPostBack)
            {
                Context.ClientPage.ClientResponse.Alert("Alert");
                args.WaitForPostBack();
            }
           
        }
    }

3) Create an application with one button. The handler for the button click event has the following code:

public class TestForm : ApplicationForm
    {
        protected Button TestButton;
        protected override void OnLoad(System.EventArgs e)
        {
            base.OnLoad(e);
            TestButton.OnClick += TestButton_OnClick;
        }
        void TestButton_OnClick(object sender, System.EventArgs e)
        {         
            CommandContext context = new CommandContext();
            AlertMessage n = new AlertMessage();

            n.Execute(context);
        }
}

4) Clicking the button throws an exception: “Unable to serialize the session state in 'StateServer' and 'SQLServer'mode. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as the result non-serializable objects”.

Problem solution:

Mark your AlertMessage command class as [Serializable].

Scenario 2

1) Add any method to your TestForm class (e.g TestMethod)

public void TestMethod()
        {

        }

2) Change the AlertMessage class:

public delegate void ExecuteCallback(string id);
    [Serializable]
    public class AlertMessage : Create
    {
        public ExecuteCallback callback;
        public override void Execute(CommandContext context)
        {
            Context.ClientPage.Start(this, "Pipeline");
        }
        public AlertMessage (ExecuteCallback callback)
        {
            this.callback = callback;
        }
        protected void Pipeline (ClientPipelineArgs args)
        {
            if (!args.IsPostBack)
            {
                Context.ClientPage.ClientResponse.Alert("Alert");
                args.WaitForPostBack();
            }
        }     
    }

3) Modify the handler for the button click event as follows:

void TestButton_OnClick(object sender, System.EventArgs e)
        {
          
            CommandContext context = new CommandContext();
            CreateItemTest createCommand = new CreateItemTest(delegate
            {
                OnRedrow();
                Context.ClientPage.ClientResponse.Redraw();
            });
            createCommand.Execute(context);
        }

4) Clicking the button throws an exception: “Unable to serialize the session state in 'StateServer' and 'SQLServer'mode. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as the result non-serializable objects”.

Problem solution:
The anonymous method here invokes the instance method of the form class. Obviously, when serializing a delegate to this method (as a part of the AlertMessage object), .NET will try to serialize the form object. It looks like anonymous methods won't "just work" when you deal with UI pipelines; you always have to make sure that the declaring class is [Serializable].

There are two possible solutions here:
  - fall back on usual methods and declare that a static method should be used as the pipeline callback
  - make a nested class with all the necessary data for the callback, mark it [Serializable] and move the callback to this class.