2

Resolved

Orchard WorkFlow and Session State

description

I am using Orchard version 1.7, and am trying to create a Workflow triggered by a Content Item (CustomForm) being created.
I create the empty Workflow OK, and then drag a "Content Created" item into it. I then edit it and select a content type of "CustomForm".
When I try to save it, I get the error shown below.
On researching this error, I discovered it relates to how session state is stored by the web site. As I am on shared hosting, I need to configure this as "StateServer" to avoid session timeouts. i.e.

<sessionState mode="StateServer" cookieless="false" timeout="20" />

If I remove this line from web.config, it works OK.

Any ideas?

Error Details start here
Server Error in '/OrchardTFS' Application.
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.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: 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.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[SerializationException: Type 'Orchard.Workflows.ViewModels.UpdatedActivityModel' in Assembly 'Orchard.Workflows, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +14328213
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +408
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +420
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +532
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) +969
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteArrayMember(WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, Object data) +628
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteArray(WriteObjectInfo objectInfo, NameInfo memberNameInfo, WriteObjectInfo memberObjectInfo) +940
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) +493
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +633
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +322
System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1487

[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.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +2485735
System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value, BinaryWriter writer) +49
System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer) +746
System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item, Stream stream) +336
System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item, Int32 initialStreamSize, Byte[]& buf, Int32& length, Boolean compressionEnabled) +99
System.Web.SessionState.OutOfProcSessionStateStore.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) +3828900
System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs) +1021
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18044

comments

CraigLittlewood wrote Aug 21, 2013 at 9:41 AM

I have looked into this further and found what the problem is. In the Orchard.WorkFlows module, the object UpdatedActivityModel() in AdminEditViewModel is not serializable for two reasons. Firstly, it has not been marked with the [Serializable] attribute, and secondly cause it contains a FormCollection property, which is also not serializable. To fix, I changed the FormCollection to a NameValueCollection, which required some minor modifications elsewhere in the model.

Changes as follows (all in Orchard.WorkFlows) based on Orchard 1.7 source image.

ViewModels/AdminEditViewModel.cs

Change definition of UpdatedActivityModel to the following;
[Serializable]
public class UpdatedActivityModel {
    public string ClientId { get; set; }
    public NameValueCollection Data { get; set; }

}
<<<

Controllers/AdminController.cs

Add following using statement at top of module
using System.Collections.Specialized;
<<<
Change line 384 to the following
            Data = new NameValueCollection(formValues)
<<<

Views/Admin/Edit.cshtml

Change line 55 to
        @: updatedActivityState = '@Html.Raw(HttpUtility.JavaScriptStringEncode(FormParametersHelper.ToJsonString(new FormCollection(model.Data))))';
<<<

Should I submit this as a patch request? If so, what is the procedure given source control is now Git?

CraigLittlewood wrote Aug 21, 2013 at 9:48 AM

Didn't pay attention to how this tool worked with regard to inserting source code! Here are the changes again!

ViewModels/AdminEditViewModel.cs

Change definition of UpdatedActivityModel to the following;
[Serializable]
public class UpdatedActivityModel {
    public string ClientId { get; set; }
    public NameValueCollection Data { get; set; }

}

Controllers/AdminController.cs

Add following using statement at top of module
using System.Collections.Specialized;
Change line 384 to the following
            Data = new NameValueCollection(formValues)

Views/Admin/Edit.cshtml

Change line 55 to
        @: updatedActivityState = '@Html.Raw(HttpUtility.JavaScriptStringEncode(FormParametersHelper.ToJsonString(new FormCollection(model.Data))))';

anoordende wrote Oct 18, 2013 at 12:01 PM

Yep, I too use a shared medium for maintaining session across a webfarm and seeing the same behaviour. I will update according to your instructions and will report back. Thanks and added my vote.

anoordende wrote Oct 18, 2013 at 12:49 PM

Thank you Craig for documenting the fix, it solved the issue for me too.

On your question re how to submit a patch, there are two pages outlining the old procedure using mercurial and are clearly in need of an update:

https://orchard.codeplex.com/wikipage?title=patches
http://docs.orchardproject.net/Documentation/Contributing-patches

In lieu of that, I have submitted a patch in fork 20024 and pull request created.

sebastienros wrote Oct 22, 2013 at 8:36 PM

Why is it getting into the session ?

sebastienros wrote Oct 25, 2013 at 4:44 PM

Fixed in changeset 8723dac8a01dd733f612ee43c1219af7284e0b67

Garpo wrote Oct 28, 2013 at 8:34 AM

Hi Sebastien,

I have tested this on our cert environment but the fix fails as the UpdatedActivityModel is still not marked as Serializable. Added attribute on local code and all then works fine. Can you please add Serializable attribute as follows:
    [Serializable]
    public class UpdatedActivityModel
    {
        public string ClientId { get; set; }
        public string Data { get; set; }

    }

sebastienros wrote Oct 28, 2013 at 6:47 PM

done