错误 - 未标记为可序列化

Posted

技术标签:

【中文标题】错误 - 未标记为可序列化【英文标题】:Error - is not marked as serializable 【发布时间】:2013-03-20 10:15:55 【问题描述】:

我得到的错误是:

Type 'OrgPermission' in Assembly 'App_Code.ptjvczom, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable. 

这是我的代码:

我有一个 gridview,它使用以下数据源:

 <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetOrgList" 
            TypeName="Org">
    <SelectParameters>
      <asp:SessionParameter Name="orgCodes" SessionField="UserOrgs" Type="Object" />
       <asp:Parameter DefaultValue="Y" Name="active" Type="String" />
    </SelectParameters>
 </asp:ObjectDataSource>

我在页面加载中设置会话变量,如下所示:

User cUser = new User(userid);
//make sure the user is an Admin
List<OrgPermission> orgs = new List<OrgPermission>();
foreach(OrgPermission org in cUser.orgs)
   
     if (org.type=='admin')
     
        orgs.Add(org);                       
     
   
Session["UserOrgs"] = orgs;

我的用户类如下所示:

public class OrgPermission

    public string Org  get; set;    
    public List<string> type  get; set; 

    public OrgPermission()
         

public class cUser
    
    public string userid  get; set; 
    public List<OrgPermission> orgs  get; set; 

    public clsUser(string username)
    
      //i set everything here
    

我不明白它为什么会中断,我可以在不使其可序列化的情况下使用它吗?

我尝试调试,会话变量设置得很好,然后进入 GetOrgList 并返回正确的结果,但页面没有加载,我收到上面的错误。

这是我的 GetOrgList 函数的 sn-p:

public DataTable GetOrgList(List<OrgPermission> orgCodes, string active)
    

        string orgList = null;

        //code to set OrgList using the parameter is here.

        DataSet ds = new DataSet();
        SqlConnection conn = new SqlConnection(cCon.getConn());
        SqlCommand cmd = new SqlCommand("sp_GetOrgList", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("@orgList", orgList));
        cmd.Parameters.Add(new SqlParameter("@active", active));

            conn.Open();
            SqlDataAdapter sqlDA = new SqlDataAdapter();

            sqlDA.SelectCommand = cmd;
            sqlDA.Fill(ds);

            conn.Close();
        return ds.Tables[0];
    

【问题讨论】:

【参考方案1】:

您需要为要序列化的类添加Serializable 属性。

[Serializable]
public class OrgPermission

【讨论】:

同样重要的是为什么您必须添加该可序列化标签:任何放入会话变量的对象(除了整数和布尔值等基础对象)都必须标记为可序列化。请注意,某些 .NET 类不是默认的 - 即 DataView。 我已将我的 List 类型对象类型存储在 Viewstate 中,当我尝试将其用作中继器控件的 DataSource 时,它​​向我显示了相同的错误。它是否也适用于ViewstateSession State 对我不起作用;我认为这对我来说是由其他原因引起的。此错误并不总是出现。但是当它发生时,我无能为力。无法重建或保存。我要重新启动 VS 和松散的工作。 我的 Web 服务器使用的是 IIS-7.5,但我没有 Serializable 属性,一旦我移到 IIS-10,我就会收到非序列化错误,有人可以告诉我为什么不是在 IIS-7.5 上抛出错误?我正在将一个类存储到会话密钥中。【参考方案2】:

如果您将对象存储在会话状态中,则该对象必须是可序列化的。

http://www.hpenterprisesecurity.com/vulncat/en/vulncat/dotnet/asp_dotnet_bad_practices_non_serializable_object_stored_in_session.html


编辑:

为了正确序列化会话,应用程序存储为会话属性的所有对象都必须声明 [Serializable] 属性。此外,如果对象需要自定义序列化方法,它还必须实现 ISerializable 接口。

https://vulncat.hpefod.com/en/detail?id=desc.structural.dotnet.asp_dotnet_bad_practices_non_serializable_object_stored_in_session#C%23%2fVB.NET%2fASP.NET

【讨论】:

不适用于 mode = InProc 找不到您请求的页面。 找不到您请求的页面【参考方案3】:

为了繁荣,留下我的具体解决方案,因为这是这个问题的一个棘手版本:

Type 'System.Linq.Enumerable+WhereSelectArrayIterator[T...] was not marked as serializable

由于类的字段类型为IEnumerable&lt;int&gt; 例如:

[Serializable]
class MySessionData
    public int ID;
    public IEnumerable<int> RelatedIDs; //This can be an issue

最初MySessionData 的问题实例是从一个不可序列化的列表中设置的:

MySessionData instance = new MySessionData() 
    ID = 123,
    RelatedIDs = nonSerizableList.Select<int>(item => item.ID)
;

这里的原因是 Select&lt;int&gt;(...) 返回的具体类,具有不可序列化的类型数据,您需要将 id 复制到新的 List&lt;int&gt; 以解决它。 p>

RelatedIDs = nonSerizableList.Select<int>(item => item.ID).ToList();

【讨论】:

RelatedIDs 是成员(字段),而不是属性。但是感谢您分享信息。

以上是关于错误 - 未标记为可序列化的主要内容,如果未能解决你的问题,请参考以下文章

类型“System.Web.HttpInputStream”未标记为可序列化

持久化未标记为可序列化的对象

创建 WCF 代理时数据协定未标记为可序列化

UserControl 集合未标记为可序列化

创建与插件一起使用的应用程序域:“程序集中的类型未标记为可序列化

如何识别c__DisplayClass未标记为可序列化的位置