SessionState problem after upgrading to Commerce 10.4.2

Hi all

We have just started to see problems with our solution after upgrading to Commerce 10.4.2. See the exception below. So far we only experience it during development, since we haven't moved our upgraded code to QA or production.

We are using SQL Server Session State meaning that all items placed in the session must be serializable, and the StructureMap LifecycleObjectCache is not serializable (and should not be serializable).

We are also using Owin startup and ASP.Net Identity. We have set it up like in the Quicksilver solution.

When we login, we get an HTTP 500 and see the exception below in our log.

If we then browse to /episerver, we can actually access the Episerver administration UI, but only for a short period. If I then try to brows to CMS->Admin and try to open a scheduled job, the IISExpress craches and I'm back in Visual Studio.

Have any of you experienced the same? The stacktrace does not point to any of our or Episerver code, so we are not sure where to start debugging this.

Thank you for your help.

----

2017-03-22 13:59:47,089 [23] ERROR EPiServer.Global: 1.2.5 Unhandled exception in ASP.NET
System.Web.HttpException (0x80004005): Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode. ---> System.Runtime.Serialization.SerializationException: Type 'StructureMap.Pipeline.LifecycleObjectCache' in Assembly 'StructureMap, Version=3.1.9.463, Culture=neutral, PublicKeyToken=e60ad81abae3c223' is not marked as serializable.
   at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
   at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
   at System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer)
   at System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer)
   at System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value, BinaryWriter writer)
   at System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer)
   at System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item, Stream stream)
   at System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item, Int32 initialStreamSize, Byte[]& buf, Int32& length, Boolean compressionEnabled)
   at System.Web.SessionState.SqlSessionStateStore.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem)
   at System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

#176619 Mar 23, 2017 8:10
  • Hi all

    I'm trying to debug this. I think the problem may be related to something being registered in StructureMap with the HttpSession Lifecycle. Doing some debugging and reflection turns out that the EPiServer.Commerce.Order.ProfileMigrator seems to be stored in StructureMap with HttpSessionLifecycle. But is the EPiServer.Commerce.Order.ProfileMigrator serializable? I don't think it is, and this may be what is causing our problems.

    I wonder if this is something that is new since Episerver 10.2.2 where we didn't have this problem.

    Anybody who can answer this?

    Regards

    Anders

    #176648 Mar 23, 2017 13:39
  • If anybody is interrested, then we have fixed our problem using this InitializationModule. But clearly that is just a workaround, so I have filed a support case to Episerver.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using EPiServer.Framework;
    using EPiServer.Framework.Initialization;
    using EPiServer.ServiceLocation;
    using StructureMap.Web.Pipeline;
    
    namespace SolarB2bEpiserver.Web.Site.Infrastructure.InitializationModules
    {
        [InitializableModule]
        [ModuleDependency(typeof(EPiServer.Commerce.Initialization.InitializationModule))]
        public class EpiProfileMigratorBugInitializationModule : IConfigurableModule
        {
            public void Initialize(InitializationEngine context)
            {
            }
    
            public void Uninitialize(InitializationEngine context)
            {
            }
    
            public void ConfigureContainer(ServiceConfigurationContext context)
            {
                // There seems to bave been introduced a new "feature" in Episerver 10.4.2, where the IProfileMigrator is registered with HttpSessionLifecycle
                // This means that StructureMap stores something in the HttpSession, but it is not serializable, so the SQL Server SessionState provider fails.
                // This code removes the IProfileMigrator and adds it again with a different LifeCycle.
                context.Container.EjectAllInstancesOf<EPiServer.Commerce.Order.IProfileMigrator>();
    
                context.Container.Configure(container =>
                {
                    container.For<EPiServer.Commerce.Order.IProfileMigrator>()
                        .Use<EPiServer.Commerce.Order.ProfileMigrator>()
                        .LifecycleIs<HybridLifecycle>();
                });
            }
        }
    }

    #176650 Mar 23, 2017 14:57
  • Hi Andres

    This looks like a bug IMO. We will investigate your work around and fix it ASAP.

    Thank for your solution sharing.

    /Son Do

    #176717 Mar 24, 2017 7:28
  • Hi Son Do

    I don't think you should use my work around. That is just what I can do, when I can't change the code. I think you should look at how the EPiServer.Commerce.Order.IProfileMigrator is registered in your internal initialization and then fix that instead :)

    I have also created a support ticket that have been assigned to Paul West, so please keep coordinate with him, so that you don't do double work.

    Regards

    Anders

    #176718 Mar 24, 2017 8:11
  • Yeah, I totally agree with you :)

    #176725 Mar 24, 2017 9:08
  • This bug fix has been released as part of Commerce 10.5.0 - see http://world.episerver.com/documentation/Release-Notes/ReleaseNote/?releaseNoteId=COM-4206.

    #177638 Edited, Apr 14, 2017 21:26
  • Hi Bob

    Thank you for your update.

    I guess it should be this link: http://world.episerver.com/documentation/Release-Notes/ReleaseNote/?releaseNoteId=COM-4206 instead :)

    We will look into upgrading our solution to the latest version.

    Regards

    Anders

    #177729 Apr 18, 2017 8:53
First   1   Last