OrchardCMS / Orchard

Orchard is a free, open source, community-focused Content Management System built on the ASP.NET MVC platform.
https://orchardproject.net
BSD 3-Clause "New" or "Revised" License
2.38k stars 1.12k forks source link

Orchard WorkFlow and Session State #3852

Closed orchardbot closed 9 years ago

orchardbot commented 11 years ago

CraigLittlewood created: https://orchard.codeplex.com/workitem/20024

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.

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

orchardbot commented 11 years ago

CraigLittlewood commented:

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?

orchardbot commented 11 years ago

CraigLittlewood commented:

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))))';
orchardbot commented 11 years ago

anoordende commented:

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.

orchardbot commented 11 years ago

anoordende commented:

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.

orchardbot commented 11 years ago

@sebastienros commented:

Why is it getting into the session ?

orchardbot commented 11 years ago

@sebastienros commented:

Fixed in changeset 8723dac8a01dd733f612ee43c1219af7284e0b67

orchardbot commented 11 years ago

@Garpo001 commented:

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; }

    }
orchardbot commented 11 years ago

@sebastienros commented:

done