无法序列化会话状态。第2部分

时间:2011-05-05 09:35:40

标签: c# asp.net linq session serialization

解决昨天(Unable to serialize the session state)错误后,我现在遇到了这个错误(在同一页面上)。

  '/'应用程序中的服务器错误。   无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET将序列化会话状态对象,因此不允许使用不可序列化的对象或MarshalByRef对象。如果自定义会话状态存储在“自定义”模式下完成类似的序列化,则适用相同的限制。   描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中的起源位置的更多信息。

     

异常详细信息:System.Web.HttpException:无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET将序列化会话状态对象,因此不允许使用不可序列化的对象或MarshalByRef对象。如果自定义会话状态存储在“自定义”模式下完成类似的序列化,则适用相同的限制。

来源错误:

  

执行期间生成了未处理的异常   当前的网络请求。有关的来源和位置的信息   可以使用下面的异常堆栈跟踪来识别异常。

堆栈追踪:

  

[SerializationException:Type   汇编中的'System.Data.Linq.ChangeTracker + StandardChangeTracker'   'System.Data.Linq,Version = 4.0.0.0,Culture = neutral,   PublicKeyToken = b77a5c561934e089'未标记为可序列化。]   System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType   型号)+9452985   System.Runtime.Serialization.FormatterServices.GetSerializableMembers(类型   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转换器,   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(对象   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):无法序列化会话状态。在   在“StateServer”和“SQLServer”模式下,ASP.NET将序列化会话   状态对象,因此不可序列化的对象或   不允许MarshalByRef对象。同样的限制适用   如果类似的序列化由自定义会话状态存储在中完成   '自定义模式。]   System.Web.Util.AltSerialization.WriteValueToStream(Object value,   BinaryWriter作者)+1793   System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(对象   value,BinaryWriter writer)+34   System.Web.SessionState.SessionStateItemCollection.Serialize(的BinaryWriter   作家)+638   System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData   item,Stream stream)+244   System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData   item,Int32 initialStreamSize,Byte []& buf,Int32&长度,布尔值   compressionEnabled)+67   System.Web.SessionState.OutOfProcSessionStateStore.SetAndReleaseItemExclusive(HttpContext的   context,String id,SessionStateStoreData item,Object lockId,Boolean   newItem)+114   System.Web.SessionState.SessionStateModule.OnReleaseState(对象   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   版本信息:Microsoft .NET Framework版本:4.0.30319; ASP.NET版本:4.0.30319.1

我现在在我的LINQ数据库文件中放了一个序列化类型。

[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 个答案:

答案 0 :(得分:4)

使用BinaryFormatter(包括此会话状态提供程序)时,图表中的所有类型都必须通过[Serializable]ISerializable进行序列化。这里最常见的“问题”是事件。通常你可以添加:

[field:NonSerialized]

任何类似字段的事件声明,即

[field:NonSerialized]
public event EventHandler FooChanged;

但显然这在生成的代码中不方便。

IMO,这里真正的问题是在状态中使用富对象。会话状态和缓存对象应该是 bare-bones 版本 - 基本的DTO,只需要最少的麻烦和复杂性 - 只是数据(我认为完全不变性或冰棒不变性也是一个很好的选择) )。我会重构为你想要存储的东西添加一个DTO,然后存储它。

另一种方法是在交换序列化程序的过程中更改状态实现。在DBML设计器中,您可以使LINQ模型“单向”,这意味着DataContractSerializer将与它们一起使用;所以DataContractSerializer可以进行合理的交换;但是,撰写提供商 努力工作 并且与您的业务需求无关。我只想写DTO; p

最后一个选项是在ISerializable中实施partial class,并且只存储/获取您实际需要的值

(除了事件之外,导致BinaryFormatter无法序列化的对象的任何其他字段失败)