代码之家  ›  专栏  ›  技术社区  ›  Øyvind Skaar

对标记为非SerializedAttribute的成员执行System.Web.UI.Page.SaveAllState()中的序列化异常

  •  1
  • Øyvind Skaar  · 技术社区  · 15 年前

    我在包含自定义控件的页面上得到一个序列化错误。控件有一个成员( dataContext )属于某一类型( EntityContext )它是不可序列化的,并标记为不可序列化的。

    这是错误:

    在中键入“Entities.EntityContext” 程序集“…”未标记为 可序列化。

    [序列化异常:类型 '..Entities.EntityContext' 在程序集中“…”是 未标记为可序列化。]
    System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType 7733643型
    System.Runtime.Serialization.FormatterServices.GetSerializableMembers(类型 类型,流式上下文上下文)+258
    system.runtime.serialization.formatters.binary.writeObjectinfo.initmemberinfo()。 +111 system.runtime.serialization.formatters.binary.writeObjectinfo.initserialize(对象 OBJ,I箭头选择器 代理网关选择器,流式上下文 上下文,serobjectionfoinit 血清目标信息素,IFormaterConverter Converter,ObjectWriter对象编写器) +161 system.runtime.serialization.formatters.binary.writeObjectInfo.serialization(对象 OBJ,I箭头选择器 代理网关选择器,流式上下文 上下文,serobjectionfoinit 血清目标信息素,IFormaterConverter Converter,ObjectWriter对象编写器) +51 system.runtime.serialization.formatters.binary.objectWriter.serialization(对象 图表,标题[]inheaders, _二进制编写器serwriter,布尔值fcheck)+410
    system.runtime.serialization.formatters.binary.binaryFormatter.serialization(流 序列化流,对象图, header[]头,布尔值fcheck)+134 system.runtime.serialization.formatters.binary.binaryFormatter.serialization(流 序列化流,对象图)+13 System.Web.UI.ObjectStateFormatter.SerializeValue(SerializerBinaryWriter 作者,对象值)+4966

    [参数异常:序列化时出错 价值 '..Entities.EntityContext' 类型的 '..Entities.EntityContext.'] System.Web.UI.ObjectStateFormatter.SerializeValue(SerializerBinaryWriter 写入器,对象值)+5425
    System.Web.UI.ObjectStateFormatter.Serialize(流 输出流,对象状态图+163 System.Web.UI.ObjectStateFormatter.Serialize(对象 状态图+ 99
    System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Serialize(对象 状态)+ 37
    System.Web.UI.Util.SerializeWithAssert(IStateFormatter 格式化程序,对象状态图)+55
    system.web.ui.hiddenfieldPageStatePersister.save()。 +143 system.web.ui.page.savepageStateToPersistenceMedium(对象 州)+190
    system.web.ui.page.saveallstate()。 +1466 system.web.ui.page.processRequestMain(布尔值 includeStagesBeforeAsyncPoint,布尔值 异步点后的includeStagesAfterAsyncPoint)+5477

    这是控制:

    public class EntityDataSource : ObjectDataSource
    {
        [NonSerialized] private EntityContext dataContext;
    
        /// <summary>
        /// Gets the data context. (This is used by the page at runtime.)
        /// </summary>
        /// <value>The data context.</value>
        // ReSharper disable MemberCanBePrivate.Global
        public EntityContext DataContext
        // ReSharper restore MemberCanBePrivate.Global
        {
            get { return dataContext; }
        }
    
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            dataContext = new EntityContext(SessionProvider.GetContext());
        }
    
        /// <summary>
        /// Viewstate is not implemented. This value allways return <c>false</c>.
        /// </summary>
        /// <exception cref="NotSupportedException">Exception is thrown when setting this value.</exception>
        [Browsable(false)]
        public override bool EnableViewState
        {
            get
            {
                return false;
            }
            set
            {
                //Throws exception if value is true.
                if (value)
                {
                    throw new NotSupportedException("Viewstate is not enabled on this control.");
                }
            }
        }
    
        public override void Dispose()
        {
            if (DataContext != null)
            {
                DataContext.Dispose();
            }
    
            base.Dispose();
        }
    }
    

    似乎这一页不尊重 NonSerializedAttribute . 我在名称空间中省略了公司和产品名称。

    5 回复  |  直到 8 年前
        1
  •  2
  •   MaLio    15 年前

    如果我理解这个问题…

    以它为例,这个实例正在被序列化,而你不希望如此。好吧,如果您无法更改实例的处理方式,请更改它的序列化方式。实现System.Runtime.Serialization.ISerializable,只需在反序列化构造函数中设置初始状态(实现接口时需要)。这样至少可以绕过异常(确保这仍然会导致正确的行为),并且不会向流中添加任何内容(类型信息除外)。由于不需要状态持久化,因此您只需不向字典中添加项。

        2
  •  1
  •   Michael Hart    15 年前

    确保添加 SerializableAttribute EntityDataSource 班级:

    [Serializable]
    public class EntityDataSource : ObjectDataSource
    {
        [NonSerialized] private EntityContext dataContext;
        // etc...
    }
    

    这个 [NonSerialized] 如果类未标记为,则忽略属性 [Serializable] .

    系统是否真的可以序列化您想要的类是另一回事。

        3
  •  0
  •   Dabblernl    15 年前

    您是否也尝试将[非序列化]属性放在属性上? 此外,如果您在类中使用的任何类型(在示例中可能已省略)继承了您遇到问题的EntityContext。

        4
  •  0
  •   Marc Gravell    15 年前

    还有什么你没有在控制面板上显示的吗?尤其是;你继承自 ObjectDataSource -我假设您在某个时刻给它数据上下文(或相关对象)?

    我个人不希望 数据源控件 应序列化。不是这样的 ISerializable 也不 [Serializable] ,首先。此外,它还有很多事件…事件很少是序列化的朋友(使用 BinaryFormatter 至少。

    最终,您应该序列化 状态 但是 数据源控件 不是状态-它或多或少是UI实现的一部分。只是尝试序列化 香草 数据源控件 足以引发异常。

    简言之,我认为你不应该把这种控制包括在 SaveAllState ,可能标记 你控制的领域 作为 [NonSerialized] .

        5
  •  0
  •   David Kiff    15 年前

    我不确定我完全理解…您试图序列化一个不可序列化的类,并且想知道为什么不应用非序列化属性?

    我有什么东西不见了吗?