Serialization issue Orchard 1.8.1

Topics: Administration
Aug 19, 2014 at 7:58 AM
Edited Aug 19, 2014 at 8:00 AM
Hi,

We are currently in the process of upgrading our Orchard websites from 1.7.2 to 1.8.1 on Windows 2008 R2 server with IIS 7.5 with .Net Framework 4.5.1 in a Network Load Balanced environment.

Every so often Orchards log an error about serialization exception in the log file, see at the bottom of this post. I've done some research and our head of development says it might be related to a machine key issue in IIS.

I've set the machine to the following on each server but the error is still occurring, this only happens when running the server in NLB, on a single server it doesn't occur.

Machine key ABC1234BCA...(some key generated by IIS)
[ ] Automatically generate at runtime
[ ] Generate a unique key for each application


Any advice would be greatly appreciated.

ORCHARD ERROR:
2014-08-19 08:14:03,908 [11] Orchard.ContentManagement.Drivers.Coordinators.ContentPartDriverCoordinator - Default - SerializationException thrown from IContentPartDriver by Drivers.SelectorDriver
http://website.com/
System.Runtime.Serialization.SerializationException: Unable to find assembly 'App_Web_.csproj.df0703db.bmfp-mhr, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage)
at System.Web.Util.AltSerialization.ReadValueFromStream(BinaryReader reader)
at System.Web.SessionState.SessionStateItemCollection.ReadValueFromStreamWithAssert()
at System.Web.SessionState.SessionStateItemCollection.DeserializeItem(String name, Boolean check)
at System.Web.SessionState.SessionStateItemCollection.get_Item(String name)
at Drivers.SelectorDriver.Display(SelectorPart part, String displayType, Object shapeHelper)
at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
at Orchard.ContentManagement.Drivers.ContentPartDriver1.Orchard.ContentManagement.Drivers.IContentPartDriver.BuildDisplay(BuildDisplayContext context) in d:\Developement\Orchard\Orchard-Version181\Orchard.Source.1.8.1\src\Orchard\ContentManagement\Drivers\ContentPartDriver.cs:line 27
at Orchard.ContentManagement.Drivers.Coordinators.ContentPartDriverCoordinator.<>c__DisplayClassa.<BuildDisplay>b__9(IContentPartDriver driver) in d:\Developement\Orchard\Orchard-Version181\Orchard.Source.1.8.1\src\Orchard\ContentManagement\Drivers\Coordinators\ContentPartDriverCoordinator.cs:line 47
at Orchard.InvokeExtensions.Invoke[TEvents](IEnumerable
1 events, Action`1 dispatch, ILogger logger) in d:\Developement\Orchard\Orchard-Version181\Orchard.Source.1.8.1\src\Orchard\InvokeExtensions.cs:line 17
Coordinator
Aug 19, 2014 at 6:42 PM
IS it possible that some automatic deployment would overwrite the web.config from time to time? Have you tried to define the MachineKey directly in your source web.config which is pushed on every machine?

What kind of "distributed/shared" session storage are you using ?
Aug 20, 2014 at 7:23 AM
Thanks for the replay.

We are currently using Microsoft Web Farm Framework to keep the servers in sync with regards to content and configurations excluding the Orchard cache, dependencies and log files.

We use a fixed Machine key for each website and made sure that key is on all the servers. We also found out that changing the order in web.config file for the Machine Key seems to have solved some of the issues but that doesn't really make sense to me.

To manage the session we use the ASP Session State database. I want to know if it is also need to upgrade or recreate this database after we did the .Net Framework 4.5.1 upgrade?
Sep 22, 2014 at 4:54 PM
Edited Sep 22, 2014 at 5:00 PM
Hi iondark,

Have you managed to find a resolution to this issue? We too are experiencing this issue and it has become a show-stopper for our main site (kulula.com) migration to Orchard 1.8.1. The site as is works perfectly on Orchard 1.7.2. on a web farm. However migrating onto Orchard 1.8.1 on .Net 4.5.1 enabled Farm it fails.

We have tried all solutions suggested in articles referring to .Net 4.5.1 Session State but to no avail. The session state seems to persist to the database but unfortunately any session object retrieved from Session fails with issue as you described above. When stepping through the session keys and logging them we see them as available and even the typeof() method returns the correct Type, however when the object is retrieved boom serialization error...

Sebastien, is there somebody on the Asp.Net team that can maybe shed some light on this issue please? We have been battling over a month now.
Sep 22, 2014 at 6:28 PM
Open an issue, seems that something is no more serializable
Coordinator
Sep 22, 2014 at 6:37 PM
@Garpo, would you mind sharing your stack trace too ?
Sep 23, 2014 at 8:50 AM
I have wrapped the exception into an Application exception, hence the custom message:

<hostVersion>4.0.30319.18444</hostVersion>
<applicationName>Orchard.kulula.com</applicationName>
<errorDate>2014-09-22T17:39:59.9213868+02:00</errorDate>
<errorMessage>
(SelectorDriver - Retrieve Basket from Session)
System.Runtime.Serialization.SerializationException: Unable to find assembly 'App_Web_comair.kulula.csproj.df0703db.aybku_wy, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
</errorMessage>
<errorDetail>
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage)
at System.Web.Util.AltSerialization.ReadValueFromStream(BinaryReader reader)
at System.Web.SessionState.SessionStateItemCollection.ReadValueFromStreamWithAssert()
at System.Web.SessionState.SessionStateItemCollection.DeserializeItem(String name, Boolean check)
at System.Web.SessionState.SessionStateItemCollection.get_Item(String name)
at Comair.kulula.Drivers.SelectorDriver.Display(SelectorPart part, String displayType, Object shapeHelper)
</errorDetail>
<source>mscorlib</source>
<className>GetAssembly</className>
<functionName>System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo</functionName>
Coordinator
Sep 23, 2014 at 7:58 PM
Answer from the ASP.NET master, it's typically because what you put in your Session is in an assembly that got recompiled dynamically. For instance in App_Code, in a .cshtml file or in an Orchard module which has changed and got recompiled. Everything you put in your sessions should be in a different class assembly.

And I assume because you are using different servers, because Orchard can dynamically compile your assemblies you get different dlls on the servers. So ensure these objects are in a specific assembly.
Sep 24, 2014 at 8:47 AM
Thank you Sebastien, that makes sense. Will refactor objects into a separate assembly and re-try.
Oct 2, 2014 at 4:49 PM
Thanks again for help Sebastien, we are now live on 1.8.1 after some refactoring and all is purring along nicely.

So to re-cap on this issue, if you plan to persist objects across server farm, ensure the objects are not part of the module, theme or any other assembly that could possibly dynamically compile.

Lesson learnt and noted for future iterations.