Erro - não está marcado como serializável

o erro que estou a ter é:

Type 'OrgPermission' in Assembly 'App_Code.ptjvczom, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable. 
Aqui está o meu código:

Eu tenho uma vista de olhos, que usa a seguinte fonte de Dados:

 <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>

configurei a variável de sessão na minha carga de página assim:

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;
A minha classe de utilizadores é assim:
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
    }
}
Não percebo porque está a partir-se, posso usá-lo sem torná-lo serializável?

Tentei depurar, e a variável de sessão está muito bem, depois entra no GetOrgList e volta. resultados corretos, mas a página não carrega e eu recebo o erro acima.

Aqui está um trecho da minha função Getorglista:
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];
    }
Author: Raghavendra, 2013-03-29

3 answers

Tem de adicionar um atributo Serializable à classe que deseja serializar.

[Serializable]
public class OrgPermission
 160
Author: burning_LEGION, 2020-05-14 12:02:25

Se você armazenar um objecto no estado de sessão, esse objecto deve ser serializável.

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


Editar:

Para que a sessão seja serializada correctamente, todos os objectos que a aplicação guarda como atributos de sessão devem declarar o atributo [serializável]. Adicionalmente, se o objecto necessitar de métodos de serialização personalizados, ele também deve implementar a interface Iserializável.

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

 17
Author: nimeshjm, 2017-08-24 17:11:57
Deixando a minha solução específica para a prosperidade, pois é uma versão complicada deste problema:

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

Devido a uma classe com um atributo IEnumerable<int> eg:

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

Originalmente a instância de problema de MySessionData foi definida a partir de uma lista não serializável:

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

A causa aqui é a classe de concreto que o Select<int>(...) devolve, tem dados de tipo que não são serializáveis, e você precisa copiar os ids para um List<int> fresco para resolvê-lo.

RelatedIDs = nonSerizableList.Select<int>(item => item.ID).ToList();
 1
Author: Jono, 2018-10-26 10:19:40