来自 System.Web.UI.Page.SaveAllState() 对标有 NonSerializedAttribute 的成员的 SerializationException

Posted

技术标签:

【中文标题】来自 System.Web.UI.Page.SaveAllState() 对标有 NonSerializedAttribute 的成员的 SerializationException【英文标题】:SerializationException from System.Web.UI.Page.SaveAllState() on a member marked with NonSerializedAttribute 【发布时间】:2010-11-20 21:22:10 【问题描述】:

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

这是错误:

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

[序列化异常:类型 '...实体.EntityContext' 在大会 '...' 是 未标记为可序列化。] System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType 类型)+7733643 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(类型 类型,StreamingContext 上下文)+258 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +111 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(对象 obj,ISurrogateSelector 代理选择器,StreamingContext 上下文,SerObjectInfoInit serObjectInfoInit, IFormatterConverter 转换器,ObjectWriter objectWriter) +161 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(对象 obj,ISurrogateSelector 代理选择器,StreamingContext 上下文,SerObjectInfoInit serObjectInfoInit, IFormatterConverter 转换器,ObjectWriter objectWriter) +51 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(对象 图,Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +410 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(流 序列化流,对象图, 标头 [] 标头,布尔 fCheck) +134 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(流 序列化流,对象图)+13 System.Web.UI.ObjectStateFormatter.SerializeValue(SerializerBinaryWriter 作家,对象值)+4966

[ArgumentException: 序列化错误 价值 '...实体.EntityContext' 类型 '...Entity.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。 我从命名空间中省略了公司和产品名称。

【问题讨论】:

我想我应该提出一个更准确的问题,因为大多数人都误解了我的问题。不过,感谢您的努力。 【参考方案1】:

如果我理解问题...

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

【讨论】:

这是我最终得到的解决方法。不过,它几乎看起来像是一个错误。【参考方案2】:

确保将SerializableAttribute 添加到EntityDataSource 类中:

[Serializable]
public class EntityDataSource : ObjectDataSource

    [NonSerialized] private EntityContext dataContext;
    // etc...

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

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

【讨论】:

好吧,这个类并不是真正可序列化的,所以它不能解决我的问题。 在页面标记中声明了继承ObjectDataSource的控件,因此在保存视图状态时被页面序列化。我根本不需要序列化。 如果类未标记为 [Serializable],则忽略 NonSerialized 属性。您是否可以实际序列化您的课程取决于您的情况。我正在回答你为什么会看到你所看到的问题。【参考方案3】:

您是否尝试将 [NonSerialized] 属性也放在属性上? 此外,如果您在类中使用的任何类型(并且您可能在示例中省略)继承自 EntityContext,那么您就有麻烦了。

【讨论】:

[NonSerialized] 只能修饰字段。没有任何东西继承自 EntityContext。 好的,但后来我认为问题不在于 [NonSerialized] 属性被忽略。【参考方案4】:

还有什么你没有在控件上显示的吗?特别是;你继承自ObjectDataSource - 我假设你在某个时候给它数据上下文(或一些相关对象)?

我个人并不期望ObjectDataSource 应该序列化。对于初学者来说,它不是ISerializable 也不是[Serializable]。此外,它还有很多事件……而事件很少是序列化的朋友(至少在使用 BinaryFormatter 时)。

最后,你应该序列化state;但ObjectDataSource 不是状态 - 它(或多或少)是 UI 实现的一部分。仅仅尝试序列化 vanilla ObjectDataSource 就足以导致异常。

简而言之;我认为您不应该将此控件包含在SaveAllState 的范围内,也许将您的控件的字段标记为[NonSerialized]

【讨论】:

【参考方案5】:

我不确定我是否完全理解...您尝试序列化一个不可序列化的类,并且想知道为什么未应用 NonSerialised 属性?

我有什么遗漏吗?

【讨论】:

以上是关于来自 System.Web.UI.Page.SaveAllState() 对标有 NonSerializedAttribute 的成员的 SerializationException的主要内容,如果未能解决你的问题,请参考以下文章

为啥 WCF 服务能够处理来自不同进程的调用而不是来自线程的调用

来自 viewDidAppear 的 Segue 调用有效,但不是来自 viewWillAppear

求职作业帮 C++方向面经

来自 CWnd 的 ReleaseDC 覆盖来自 winuser 的 ReleaseDC

来自麦克风的声音与来自扬声器的声音

Liferay,来自搜索的 Freemarker 错误模板,但不是来自其他链接