Retrieve List<> from Session Variable

  • Thread starter Thread starter Jacques Oberto
  • Start date Start date
J

Jacques Oberto

Hi All,

I am having problems retrieving a List of objects
from a Session variable on page Default2.aspx.
A "casting" error is generated. Please see code
below. Could anybody help?
Thanks,

Jacques


===============
Default.aspx.cs
===============
List<Person> people = new List<Person>();
public class Person
{
public int age;
public string name;
public Person(int age, string name)
{
this.age = age;
this.name = name;
}
}

protected void Button1_Click(object sender, EventArgs e)
{
people.Add(new Person(50, "Fred"));
people.Add(new Person(30, "John"));
people.Add(new Person(26, "Andrew"));
Session["mylist"] = people;
Response.Redirect("Default2.aspx");
}

===============
Default2.aspx.cs
===============
List<Person> people = new List<Person>();
public class Person
{
public int age;
public string name;
public Person(int age, string name)
{
this.age = age;
this.name = name;
}
}

protected void Page_Load(object sender, EventArgs e)
{
if (Session["mylist"] != null)
{
//casting problem line below
people = (List<Person>)Session["mylist"];
}
}

====================
 
Hi All,

I am having problems retrieving a List of objects
from a Session variable on page Default2.aspx.
A "casting" error is generated. Please see code
below. Could anybody help?
Thanks,

Jacques

===============
Default.aspx.cs
===============
List<Person> people = new List<Person>();
public class Person
{
    public int age;
    public string name;
    public Person(int age, string name)
    {
        this.age = age;
        this.name = name;
    }

}

protected void Button1_Click(object sender, EventArgs e)
{
    people.Add(new Person(50, "Fred"));
    people.Add(new Person(30, "John"));
    people.Add(new Person(26, "Andrew"));
    Session["mylist"] = people;
    Response.Redirect("Default2.aspx");

}

===============
Default2.aspx.cs
===============
List<Person> people = new List<Person>();
public class Person
{
    public int age;
    public string name;
    public Person(int age, string name)
    {
        this.age = age;
        this.name = name;
    }

}

protected void Page_Load(object sender, EventArgs e)
{
    if (Session["mylist"] != null)
    {
        //casting problem line below
        people = (List<Person>)Session["mylist"];
    }

}

====================

Move public class declaration out of both webform classes to Person.cs

public class Person
{
public int age;
public string name;
public Person(int age, string name)
{
this.age = age;
this.name = name;
}
}

and try again.
 
Move public class declaration out of both webform classes to Person.cs

Thanks again Alexey: it works now.
But why was it broken in the first place ?

Jacques
 
Thanks again Alexey: it works now.
But why was it broken in the first place ?

How many Person classes were accessible in the application the way you had
it originally coded? Answering that question should give you a good idea
why it might have ended up with a casting error.

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
How many Person classes were accessible in the application the way you had
it originally coded? Answering that question should give you a good idea
why it might have ended up with a casting error.

Hi Gregory,

The code would not compile with the Person class on only one page.
On the other hand, the compiler did not complain with one Person
class on each page until it tried to access the Session variable.
As a newbie, I assumed that the two same classes could no see each
other on two different pages...

Jacques
 
The code would not compile with the Person class on only one page.
On the other hand, the compiler did not complain with one Person
class on each page until it tried to access the Session variable.
As a newbie, I assumed that the two same classes could no see each
other on two different pages...

It would not compile the first time, as the second page could not reach
the class. When you threw it into session, the application was not sure
which class you needed to use.

Since you are a newbie, I will continue. If you clarified which of the
two classes you were using, it would work in session. Unfortunately,
that is hard with ASP.NET in default mode, as it will compile each
"page" (meaning everything in a single file) into a different assembly
and then reference that assembly alone.

With certain ASP.NET setups, the two class version would not compile,
unless you stuck the different pages into different namespaces, as it
would have a clash between the two.

NOTE: In most projects, having two classes with the same name in the
same namespace (same folder in Visual Studio by default), it will not
compile. ASP.NET is a special exception due to the fact that you can
deploy without compiling and have it compile a page at a time on the
fly. In addition, you can deploy with separate assemblies and still have
multiple classes with the same name, as the pointer file (ASPX) will
point to a particular assembly. Frankly, I consider the model a bit
kludgy, but much of it was necessary to accomplish a projectless ASP.NET
model.

Hope this gives a bit more insight, or at least gives some insight in
how web apps in .NET are different from other app types.

The correct solution, as stated, was to move the class out, as it could
then be contacted by each page, as well as the session. I would put it
in a library, personally, rather than App_Code, but I view the UI as a
faceplate for an application and not part of the application proper. My
ASP.NET apps rarely have much code, except displaying information and
"packaging" input to go into the app. Using this paradgim, I can easily
change the app type from ASP.NET to windows forms, etc.

Peace and Grace,

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
It would not compile the first time, as the second page could not reach
the class. When you threw it into session, the application was not sure
which class you needed to use.

Since you are a newbie, I will continue. If you clarified which of the
two classes you were using, it would work in session. Unfortunately,
that is hard with ASP.NET in default mode, as it will compile each
"page" (meaning everything in a single file) into a different assembly
and then reference that assembly alone.

With certain ASP.NET setups, the two class version would not compile,
unless you stuck the different pages into different namespaces, as it
would have a clash between the two.

NOTE: In most projects, having two classes with the same name in the
same namespace (same folder in Visual Studio by default), it will not
compile. ASP.NET is a special exception due to the fact that you can
deploy without compiling and have it compile a page at a time on the
fly. In addition, you can deploy with separate assemblies and still have
multiple classes with the same name, as the pointer file (ASPX) will
point to a particular assembly. Frankly, I consider the model a bit
kludgy, but much of it was necessary to accomplish a projectless ASP.NET
model.

Hope this gives a bit more insight, or at least gives some insight in
how web apps in .NET are different from other app types.

The correct solution, as stated, was to move the class out, as it could
then be contacted by each page, as well as the session. I would put it
in a library, personally, rather than App_Code, but I view the UI as a
faceplate for an application and not part of the application proper. My
ASP.NET apps rarely have much code, except displaying information and
"packaging" input to go into the app. Using this paradgim, I can easily
change the app type from ASP.NET to windows forms, etc.


Thanks Gregory for the useful explanation.

Jacques
 
Jacques said:
Hi Gregory,

The code would not compile with the Person class on only one page.
On the other hand, the compiler did not complain with one Person
class on each page until it tried to access the Session variable.
As a newbie, I assumed that the two same classes could no see each
other on two different pages...

Jacques

It doesn't matter if the classes see each other or not, the problem is
that you have two separate classes. Eventhough they look the same, you
can't cast one class into another.

You can only cast something into what it really is. i.e. casting from
the Object reference that you get from the session variable back into a
Person reference, but the Person class has to be the same actual class,
not just something that looks the same.
 
Thanks again Alexey: it works now.
But why was it broken in the first place ?

Jacques

The explanation here is very simple: when you create a class "inside"
another class

namespace Project1 {
public partial class Default1() {
public Person() {
} } }

then its fully qualified name would be Project1.Default1.Person

Another class will have a name as Project1.Default2.Person

This is why

Project1.Default2.Person people = (List<Project1.Default1.Person>)
Session["mylist"];

would give an error.
 
Back
Top