错误 - 没有标记为可序列化

73

我遇到的错误是:

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函数的片段:

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];
    }
3个回答

189

你需要向你想要序列化的类添加一个Serializable属性。

[Serializable]
public class OrgPermission

28
同样重要的是,“为什么”你必须添加可序列化标记:将任何对象放入会话变量中(除了像int和bool这样的基本对象),必须标记为可序列化。请注意,一些.NET类不是默认可序列化的,比如DataView。 - Paul
1
我已经将我的List类型对象存储在Viewstate中,当我尝试将其用作重复控件的数据源时,它显示了相同的错误。 它是否也适用于Viewstate以及Session State - sohaiby
1
对我没用,我认为这是由其他原因引起的。这个错误并不总是出现。但当它出现时,我无能为力。无法重建或保存。我只能重新启动VS并丢失工作。 - n00dles
我的Web服务器使用的是IIS-7.5,我没有使用Serializable属性。一旦我转移到IIS-10,我就会收到非序列化错误。有人能告诉我为什么在IIS-7.5上没有抛出错误吗?我正在将一个类存储到会话键中。 - love2code

19
如果你把一个对象存储在会话状态中,那么这个对象必须是可序列化的。要正确地序列化会话,应用程序存储为会话属性的所有对象都必须声明[Serializable]属性。此外,如果对象需要自定义序列化方法,则还必须实现ISerializable接口。
参考链接: http://www.hpenterprisesecurity.com/vulncat/en/vulncat/dotnet/asp_dotnet_bad_practices_non_serializable_object_stored_in_session.htmlhttps://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

1
不适用于 mode = InProc - Roland
2
您请求的页面不存在。 - JoshYates1980
您请求的页面均无法找到。 - Hoppe

5

为了将难题的解决方法留存下来,我在此提供一个具体的解决方案:

“System.Linq.Enumerable+WhereSelectArrayIterator[T...]”并没有标记为可序列化。

这是由于一个类拥有一个IEnumerable<int>类型的字段所引起的,例如:

[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<int>(...)返回的具体类别,其数据类型不可序列化,您需要将id复制到新的List<int>中以解决此问题。

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

1
RelatedIDs是一个成员(字段),而不是一个属性。但感谢您分享这个信息。 - Suncat2000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接