3
votes

After solving yesterdays ( Unable to serialize the session state ) error, I am now encountering this one (at the same page).

Server Error in '/' 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 'System.Data.Linq.ChangeTracker+StandardChangeTracker' in Assembly 'System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.] System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +9452985 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +247 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +160 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +218 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) +388 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +444 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +133 System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1708

[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) +1793 System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value, BinaryWriter writer) +34 System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer) +638 System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item, Stream stream) +244 System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item, Int32 initialStreamSize, Byte[]& buf, Int32& length, Boolean compressionEnabled) +67 System.Web.SessionState.OutOfProcSessionStateStore.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) +114 System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs) +807 System.Web.SessionState.SessionStateModule.OnEndRequest(Object source, EventArgs eventArgs) +184 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +148 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75 Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1

I have now put a serializeble type in my LINQ Database file.

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Gebruiker")]
[Serializable()]
public partial class Gebruiker { }

public partial class Gebruiker : INotifyPropertyChanging, INotifyPropertyChanged
{

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
    
    private string _GebruikerID;
    
    private string _GebruikerVoornaam;
    
    private string _GebruikerNaam;
    
    private string _GebruikerEmail;
    
    private string _GebruikerWachtwoord;
    
    private string _GebruikerPermissies;
    
    //...
}
1

1 Answers

4
votes

When using BinaryFormatter (which includes this session-state provider), all types in the graph must be serializable via [Serializable] or ISerializable. The most common "gotcha" here is events. Normally you might add:

[field:NonSerialized]

to any field-like event declarations, i.e.

[field:NonSerialized]
public event EventHandler FooChanged;

but obviously this is not convenient in generated code.

IMO, the real problem here is using rich objects in state. Session-state and cache objects should really be bare-bones versions - basic DTOs with minimum fuss and complexity - just data (I would consider full-immutability or popsicle-immutability a nice-to-have, too). I would refactor to add a DTO for the things you want to store, and just store that.

Another approach is to change your state implementation, in the process swapping the serializer. In the DBML designer you can make LINQ models "unidirectional", meaning DataContractSerializer will work with them; so DataContractSerializer might make a reasonable swap out; but writing a provider is hard work and nothing to do with your business needs. I would just write the DTO ;p

One final option is to implement ISerializable in your partial class, and only store/fetch the values you actually need.

(in addition to events, any other fields that lead to objects that are not serializable by BinaryFormatter will also fail)