【问题标题】:Unable to serialize the session state using stateserver无法使用 stateserver 序列化会话状态
【发布时间】:2013-09-27 02:27:36
【问题描述】:

我收到以下错误,想知道我们是否可以使 System.Data.Linq.EntitySet 可序列化

无法序列化会话状态。在“StateServer”和“SQLServer”模式下,ASP.NET 将序列化会话状态对象,因此不允许不可序列化的对象或 MarshalByRef 对象。如果自定义会话状态存储在“自定义”模式下完成类似的序列化,则同样的限制也适用。

说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

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

来源错误:

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

堆栈跟踪:

[SerializationException: Type 'System.Data.Linq.EntitySet`1[[NES.HiLo.Da​​ta.DAO.UserResource, NES.HiLo.Da​​ta, Version=1.0.5012.39381, Culture=neutral, PublicKeyToken=null]] ' 在程序集 'System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 中未标记为可序列化。] System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType 类型)+7738715 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(类型类型,StreamingContext 上下文)+258 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +111 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(对象 obj,ISurrogateSelector surrogateSelector,StreamingContext 上下文,SerObjectInfoInit serObjectInfoInit,IFormatterConverter 转换器,ObjectWriter objectWriter)+422 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(对象 obj,ISurrogateSelector surrogateSelector,StreamingContext 上下文,SerObjectInfoInit serObjectInfoInit,IFormatterConverter 转换器,ObjectWriter objectWriter)+51 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) +7636088 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(对象图,Header[] inHeaders,__BinaryWriter serWriter,布尔 fCheck)+461 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +134 System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1577

【问题讨论】:

    标签: c# asp.net serialization


    【解决方案1】:

    该异常实际上已经告诉您问题所在,EntitySet 不可序列化。因此,如果您使用会话数据库功能,它不能存储在会话状态中。

    EntitySet 不实现/支持这一点。因此,要将其存储在会话状态中,您必须将数据读取到您自己的对象中,然后保存它。 或者干脆不要尝试使用会话状态来“持久化”这类对象,因为通常您不想这样做(没有最佳实践)。

    【讨论】:

    • 那么这种事情的最佳实践是什么?
    • 尽可能好地实现您的应用程序无状态,以防止很多问题。每当您需要用户状态或配置文件数据时,您可以将其保存在数据库(专用表)中并将数据加载到内存中。如果需要,您可以使用分布式内存缓存来保持数据可用于多个 Web 服务器。
    【解决方案2】:

    一个最简单也是最好的解决方案之一是使用Json.NET 库。

    该库允许您将LINQ 对象双向转换为它们的JSON 表示。 例如,您可以将产品存储在视图状态中,只需几行代码:

    Product product = new Product();
    product.Name = "Apple";
    product.Expiry = new DateTime(2008, 12, 28);
    product.Price = 3.99M;
    string json = JsonConvert.SerializeObject(product);
    ViewState["product"] = json ;
    

    并把它也找回来:

    product = JsonConvert.DeserializeObject<Product>(ViewState["product"] as string);
    

    更多信息请参考这两个链接:

    1.) http://james.newtonking.com/projects/json-net.aspx

    2.) http://www.codeplex.com/json/

    如果您的应用程序使用in-process 状态管理,您将能够在会话、应用程序和缓存中存储 LINQ 对象。但是,您将无法将它们存储在视图状态中。

    原因是视图状态中存储的数据是使用二进制格式化程序序列化的。

    因此,另一种解决方案是使LINQ 类可序列化,您需要使用NonSerialized 属性标记所有System.Data.Linq.EntitySetSystem.Data.Linq.EntityRef 字段,并使用Serializable 属性标记LINQ 类.

    另一种解决方案是手动从LINQ 对象中提取数据,将其存储为某种中间格式(classstruct 等),然后手动将其转换回来。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 2013-09-24
      • 2021-07-18
      相关资源
      最近更新 更多