c# class in a session state? - c#

My senior project is building a reservation system in ASP.NET/C#. Part of my senior project is to have c# classes (and basically use everything ive learned in the past few years). One thing Im trying to do is after I instantiate a new "user" class I need it to travel between the pages. I know session states holds variables, so I figured a session state would work where I can simply type "Session["blah"]." and have access to its members. But I dont see that happening. I realize session states are HTTP context, so i doubted it would work anyway. But is there any other way in which I can accomplish what I need without instantiating a new user class every time? I know its a webpage...but im also trying to make it as much as a functional online program as I can.
Just for coder's sake, heres the code snippet im working with:
cDatabaseManager cDM = new cDatabaseManager();
string forDBPass = Encryptdata(pass_txt.Text.ToString());
string fullName = fname_txt.Text.ToString() + " " + lname_txt.Text.ToString();
cDM.regStudent(email_txt.Text.ToString(), forDBPass, fullName, num_txt.Text.ToString(), carrier_ddl.SelectedValue.ToString(), this);
//ADD - getting a cStudent
cUser studentUser = new cStudent(fullName, forDBPass, email_txt.Text.ToString());
//ADD - session states
Session["cStudent"] = studentUser;
//Session["cStudent"]. //session state will not work with what I am doing
//ADD - transfer to campus diagram
Thanks in advance!!
EDIT:
I want to thank all of you who posted and commented! Ive learned alot from this short discussion. All your answers helped me understand!

From your comment:
The issue is when I type "Session["cStudent"]." I don't have access to my functions. Example: Session["cStudent"].getName() does not give my functionality.
This is because the [] indexer for Session sets/returns objects. The compiler does not know that you stored a cUser object and so you can't access the properties directly without a cast:
string name = ((cUser)Session["cStudent"]).getName();
There are two things that could go wrong here:
If Session["cStudent"] is null you will get a NullReferenceException
If Session["cStudent"] is not really a cUser you will get an InvalidCastException
You should check these conditions and react appropriately if one of them is true.
Also, as others have pointed out, the cUser class needs to be marked as Serializable in order to be stored in Session state.

Session stores item as objects. As long as your class inherits from Object (which it does) you can store it there. Quick caveat, it stores that object using Serialization, so your class must be serializable.
Add a property to your class like so:
public cStudent CurrentStudent
{
get {
if(Session["CurrentUser"] == null)
return null;
return (cStudent)Session["CurrentUser"];
}
set {
Session["CurrentUser"] = value;
}
}

When retrieving an object value from session state cast it to appropriate type.
[Serializable]
public class student
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In Page1:
student s1 = new student();
s1.FirstName ="James";
s1.LastName = "Bond";
Session["blah"] = s1;
And when you want to access Session["blah"] in page 2
student s2 = (Session["blah"] !=null ? (student)Session["blah"] : null);
Now you can access properties of s2 as s2.FirstName, s2.LastName

Related

Use variable value to check if particular instance exists, if not - create it

I have a list of images like this:
public List<Image> imageList = new List<Image>();
I also have a picture class in order to collect and manipulate data about the images in the list:
public Class Pic {
// properties and stuff
}
And then I have a function that takes an integer as an argument. That integer corresponds to an image in the image list. What I want to do in the function is to check if an instance of the Pic class has been created for that particular image. If not, I want to create it, using the value of the variable passed into the function. The following code obviously doesn't work, but it shows what I want:
public void doStuffWithImage(int picNumber) {
// Check if instance called pic + picNumber exists
if(pic + picNumber.toString() == null) {
// Create an instance
Pic pic + picNumber.toString() = new Pic();
}
}
Suggestions on how to accomplish this?
It seems like you're trying to create individual variables pic1, pic2, etc. you'd be better off using a dictionary:
Dictionary<int, Pic> pics = new Dictionary<int, Pic>();
public void doStuffWithImage(int picNumber) {
// Check if instance called pic + picNumber exists
if(!pics.ContainsKey(picNumber)) {
// Create an instance
pics[picNumber] = new Pic();
}
}
You need to create a "registry" of known Pics. DIctionary<int,Pic> would be good collection to hold this registry. You need to store the registry itself somewhere - perhaps in the "factory" object that registers your pictures.
class PicFactory {
private readonly IDictionary<int,Pic> knownPics = new Dictionary<int,Pic>();
public Pic GetOrCreate(int id) {
Pic res;
if (knownPics.TryGetValue(id, out res)) {
return res;
}
res = new Pic(id.ToString()); // This assumes that Pic(string) exists
knownPics.Add(id, res);
return res;
}
}
This way of implementing a registry may be too primitive for your purposes - for example, if you need your registry to be concurrent, you would need to set up some sort if a locking scheme to protect the knownPics dictionary. The class that accesses pictures would need to create an instance of PicFactory, so that it could access pictures through the GetOrCreate(id) call.
If you are using .net 4.0 or more you can use Lazy type which:
Provides support for lazy initialization.
Which means that the object will be constructed not in the moment of declaration, but when first accessed.
So you can basically declare them like
List<Lazy<Pic>> ....
See Lazy<T> and the Lazy Loading Pattern in general - this is actually a common optimization technique as it defers what can add up to a lot at startup to microdelays during runtime.
Be wary about making sure the microdelays are worth it, and I advise leaving methods about which can force loading.
If you're grabbing from a list, preface with a .Any or .Contains check, and since you're looking up by name like that, consider using a Dictionary instead

IsolatedStorage and navigation

I can't sort this weird issue out and I have tried anything and everything I can think of.
I got 5 pages, everyone of them passing variables with navigation this way:
Pass:
NavigationSerice.Navigate(new Uri("/myPage.xaml?key=" + myVariable, UriKind.Relative));
Retrieve:
If (NavigationContext.QueryString.ContainsKey(myKey))
{
String retrievedVariable = NavigationContext.QueryString["myKey"].toString();
}
I open a list on many pages and one of the pages automatically deletes an item from the list actualProject (actualProject is a variable for a string list). Then, when I go so far back that I reach a specific page - the app throws an exception. Why? I have no idea.
The code that deletes the item:
// Remove the active subject from the availible subjects
unlinkedSubjects.Remove(actualSubject);
unlinkedsubjectsListBox.ItemsSource = null;
unlinkedsubjectsListBox.ItemsSource = unlinkedSubjects;
Then the page that throws the exception's OnNavigatedTo event:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (NavigationContext.QueryString.ContainsKey("key"))
{
actualProject = NavigationContext.QueryString["key"];
try
{
//Read subjectList from IsolatedStorage
subjectList = readSetting(actualProject) != null ? (List<String>)readSetting(actualProject) : new List<String>();
//Put the subjectList into the subjectListBox
subjectListBox.ItemsSource = subjectList;
//Set the subjectsPageTitle to the "actualProject" value, to display the name of the current open project at the top of the screen
subjectsPageTitle.Text = actualProject;
}
catch (Exception)
{
if (language.Equals("en."))
{
// Language is set to english
MessageBox.Show("Couldn't open the project, please try again or please report the error to Accelerated Code - details on the about page");
}
else if (language.Equals("no."))
{
// Language is set to norwegian
MessageBox.Show("Kunne ikke åpne prosjektet, vennligst prøv igjen eller rapporter problemet til Accelerated Code - du finner detaljer på om-siden");
}
}
}
}
Exception:
_exception {System.ArgumentException: Value does not fall within the expected range.} System.Exception {System.ArgumentException}
My theory:
The app kind of loads the currently opened and modified List. Is that possible? No idea.
So there are a number of ways to pass data between pages.
The way you have chosen is the least suggested.
You can use the PhoneApplicationService.Current dictionary but this is messy also if you have a ton of variables, doesn't persist after app shut down and could be simplified.
I wrote a free DLL that kept this exact scenario in mind called EZ_iso.
You can find it here
Basically what you would do to use it is this.
[DataContractAttribute]
public class YourPageVars{
[DataMember]
public Boolean Value1 = false;
[DataMember]
public String Value2 = "And so on";
[DataMember]
public List<String> MultipleValues;
}
Once you have your class setup you can pass it easily between pages
YourPageVars vars = new YourPageVars { /*Set all your values*/ };
//Now we save it
EZ_iso.IsolatedStorageAccess.SaveFile("PageVars",vars);
That's it! Now you can navigate and retrieve the file.
YourPageVars vars = (YourPageVars)EZ_iso.IsolatedStorageAccess.GetFile("PageVars",typeof(YorPageVars));
This is nice because you can use it for more than navigation. You can use it for anything that would require Isolated storage. This data is serialized to the device now so even if the app shuts down it will remain. You can of course always delete the file if you choose as well.
Please make sure to refer to the documentation for any exceptions you have. If you still need help feel free to hit me up on twitter #Anth0nyRussell or amr#AnthonyRussell.info

Trying to filter data in grid, receiving "Cannot create an instance of the static class" error

I am attempting to filter the items populated in a grid in the code behind. When I try to call my adapter from the data access layer, I am receiving the following error:
Cannot create an instance of the static class 'SFTIP.DataAccessLayer.InventoryAdapter'
The filter is meant to only display items in the grid related to the user role (AssetOwnershipProgramIds).
The error is in this segment new InventoryAdapter() of this line:
filteredList = new InventoryAdapter().GetAllByFilter(inventoryFilter);
Here is the code for the filter I am trying to build:
public List<Inventory> BindGrid()
{
List<Inventory> filteredList = new List<Inventory>();
SearchFilterInventory inventoryFilter = new SearchFilterInventory();
User currentUser;
currentUser = (Session["CurrentUser"] == null) ? (User)Session["CurrentUser"] : new User();
if (currentUser.AdminPrograms.Count > 0)
{
inventoryFilter.AssetOwnershipProgramIds.Add(currentUser.AdminPrograms[0].ReferenceId);
filteredList = new InventoryAdapter().GetAllByFilter(inventoryFilter);
}
return filteredList;
}
Can anyone provide some guidance on to where I am going wrong? I know that this is something fairly simple - this is an inherited project and I'm still trying to connect all the dots. Thank you for taking a look.
The error says it all.
You cannot create an instance of a static class. If you wanted to make that, remove static keyword from your class declaration.
MSDN says:
A static class is basically the same as a non-static class, but there
is one difference: a static class cannot be instantiated. In other
words, you cannot use the new keyword to create a variable of the
class type. Because there is no instance variable, you access the
members of a static class by using the class name itself.
Static class aren't meant to be instantiated:
A static class is basically the same as a non-static class, but there
is one difference: a static class cannot be instantiated. In other
words, you cannot use the new keyword to create a variable of the
class type. Because there is no instance variable, you access the
members of a static class by using the class name itself.
(Source: MSDN)
Likely, the GetAllByFilter method is static as well. If that's the case, your problem will be solved by changing the faulting line to this:
var filtereditems = InventoryAdapter.GetAllByFilter(inventoryFilter);
You would need a class declaration such as this, to do in the way your code is implemented.
public class InventoryAdapter
{
public InventoryAdapter() { }
public object GetAllByFilter() { }
}
or else call your method like this, if it's meant to be static / you don't own or control it:
var filtereditems = InventoryAdapter.GetAllByFilter(inventoryFilter);
Sorry about the delay in coming back back to this - been out ill & other newer work priorities.
So, - something so very simple. Made the mistake of assuming that "no one would ever do (or NOT do) that" and as programmers we ought to know better than to make that assumption, right? Anyhow, I had to add the <SelectParameters> back into ObjectDataSource in the aspx page:
<asp:ObjectDataSource ID="odsItInventory" runat="server" SelectMethod="BindGrid"
TypeName="ADRUO.GUI.UserControls.ExtendedInventoryGridUserControl">
<SelectParameters>
<asp:SessionParameter Name="User" Type="Object" SessionField="CurrentUser" />
</SelectParameters>
</asp:ObjectDataSource>
Thank you for the assistance - all of your comments were helpful, I believe each answer would have worked, had I had those parameters in the page. As it was, the param add was all that was required to resolve.

windows 8 app roaming storage with custom class

I am learning programming in windows 8 with c#. I have worked through many tutorials (such as http://msdn.microsoft.com/en-us/library/windows/apps/hh986968.aspx) in the process and I am attempting to create a simple app showing data storage. All of the examples I have been able to find store only simple strings in roaming storage. Is there a way to store more complex data there?
example: a List of a basic class Person with a name and age. I attempted to do it as:
Saving the data:
roamingSettings.Values["peopleList"] = people;
Loading the Data:
people = (List)roamingSettings.Values["peopleList"];
WinRT information: Error trying to serialize the value to be written to the application data store.
when saving the data I get the error "Data of this type is not supported"
So, maybe all you can save is string values -- but I have not seen that specified anywhere either.
Yes, you can save your values to raoming data as a collection. The solution for your problem is
ApplicationDataCompositeValue class
See http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdatacompositevalue.aspx for more information
As you mentioned, You are developing in C# , following is the code for your problem
I imagined, you have a Person class with two members
class person
{
int PersonID;
string PersonName
}
Now, to read and write values for this class, here is the code
First in the constructor of your Window class, under the InitializeComponent();, create an object of roaming settings
Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
To Write to a composition, use the following code
void write (Person Peopleobj)
{
Windows.Storage.ApplicationDataCompositeValue composite = new Windows.Storage.ApplicationDataCompositeValue();
composite["PersonID"] = Peopleobj.PersonID;
composite["PersonName"] = Peopleobj.PersonName;
roamingSettings.Values["classperson"] = composite;
}
To Read a Person object, use the following code
void DisplayOutput()
{
ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)roamingSettings.Values["classperson"];
if (composite == null)
{
// "Composite Setting: <empty>";
}
else
{
Peopleobj.PersonID = composite["PersonID"] ;
Peopleobj.PersonName = composite["PersonName"];
}
}

how to get the session variable in many pages in C#?

I have a field named username as the session variable. I have added a class which inherits the base page. Now I want the code to get the session variable in all the pages that the user moves through.
Please help me with the code.
You should be able to access the Session variable form all pages in the following way:
var username = Session["Username"].ToString();
Hope this helps
You can access your current session variables using the Session object with an index, like
var myvalue = Session["mysessionvariable"];
Use session["username"] to get the value. Then use this value as per your need
You can add a property in a base class (which is inherited from Page class) which will encapsulate the Session variable and inherit that base class in every page you create
public string UserNameInSession
{
get
{
return HttpContextCurrent["UserNameSessionKey"].ToString();
}
set
{
HttpContextCurrent["UserNameSessionKey"] = value;
}
}
And then you can use this property either to set or get the Username from/to session like
string UserName = UserNameInSession; //Get it
UserNameInSession = string.Empty();//set it

Categories

Resources