I have always stored data for a user (after they logged in) in a Session variable, so I can use that data on any page.
I found out that another way to store information globally is to store it in a class, using { get; set;}, and then calling that from any page.
Right now, I've used both these methods as a test, and they both work really well:
Session["LoginId"] = rdr["uniqueIdentifier"].ToString();
And
Member.LoginId = rdr["uniqueIdentifier"].ToString();
Where (In Member.cs)
public class Member
{
public static int Challenges { get; set; }
public static int NicknameId { get; set; }
public static string LoginId { get; set; }
public static string FriendsListId { get; set; }
public static void ClearVariables()
{
Challenges = 0;
NicknameId = 0;
LoginId = null;
FriendsListId = null;
}
}
Global.asax
void Session_End(object sender, EventArgs e)
{
Member.ClearVariables();
}
My question is, is it safe enough to store user data in a class like this, or should I stick with Session objects?
Updated for Completeness
Will this post do something like above, but for multiple users?
How to access session variables from any class in ASP.NET?
I found this approach is one of the most easy to use and with least error of chances. I think this is called Facade Design Pattern.
public class SiteSession
{
#region Attributes
private static string _siteSession = "__SiteSession__";
#endregion
#region Constructor
private SiteSession()
{
}
#endregion
#region CurrentSession
public static SiteSession Current
{
get
{
SiteSession session = HttpContext.Current.Session[_siteSession ] as SiteSession;
if (session == null)
{
session = new SiteSession();
HttpContext.Current.Session[_siteSession ] = session;
}
return session;
}
}
#endregion
#region SessionProperties
public sherserve.CustomTypes.UserTypes UserType { get; set; }
public int UserID { get; set; }
public String StaffID { get; set; }
public String Position { get; set; }
public String StaffName { get; set; }
public int TimeZone { get; set; }
public String DealerId { get; set; }
public String DealerPosition { get; set; }
public String DealerName { get; set; }
public int DealerFirmId { get; set; }
public String ClientId { get; set; }
public String ClientName { get; set; }
public String ClientBusiness { get; set; }
public String CountryCode { get; set; }
public int ClientFirmId { get; set; }
#endregion
}
Values can be store in Session like this:
SiteSession.Current.UserType = user.UserType;
And Can be obtain like this :
int userId= SiteSession.Current.UserID;
It is type safe as well.
In your case it is not safe at all since static variables in asp.net are common to all users.
Using static variables is not safe. The values set for one user would overwrite the values for another user. Static variable would mean only one variable is created and used for all sessions.
The life time of static variables is the application life time.
If your variables are meant to be user-specific (which appear to be) you will need to stick with Session variables.
I am sure that it is not working for you. An instance of class exists only as long as the request is processed. Once the request is processed, you will not be able to get the instance of the class again. In case of static variables, it is application wide and not suitable to store the user specific information.
Session is designed to handle the state of application across the post back and it is the sole purpose of session, i.e. to maintain the state of application and it is ideal for your requirement.
disadvantage off second approach is when the application restarts the variable will lose their values.but with session your data will be stored in browser cookies.
EDIT:
only use static variables when you need a application level common - shared (between all users) variables.
Sessions are created per user, while classes, in production, are alive throughout the application's whole lifetime.
Though you may not experience issues in development with only one user, in production each request will override the previous data, and could therefore pose security risks.
Stick to sessions.
Related
How can I configure the get and set of an object that belongs to a custom class?
I have the following situation (and it’s not working):
public class SurveyETA
{
public static string Question1 { get; set; }
public static string Question2 { get; set; }
public static string Question3 { get; set; }
public static string Question4 { get; set; }
public static string Question5 { get; set; }
public static string Question6 { get; set; }
}
public static SurveyETA RespondentETA = new SurveyETA()
{
Question1 {
get { return HttpContext.Current.Session["RespondentQ1"] == null ? "" : HttpContext.Current.Session["jSession326"].ToString();}
set { HttpContext.Current.Session["RespondentQ1"] = value; }}
};
My intention is that this object has properties whose content is unique and specific to each user. If I only use a static instance, what happens is that all users share the content.
There really isn't enough information here to answer your particular question about your particular situation.
That said, I can attempt to make some assumptions about what you may want to consider based on what you're saying.
You talk about having individual users. Where are those users stored? If they're stored in a database, then you can use queries against that database to return information that is specific to those users.
The specific information you have about those users will also be stored in your database, and that information will be associated with those users through the user id for each user (among other things. This is a very high level overview of how this works).
TL;DR:
Query whatever database storage mechanism you're using to get the information you need for each user. Return that information and associate it with an instance of your SurveyETA class.
I have a method as follows which gets data and stores them to specific variables. I also have two static variables that preserves their value if a condition is met. My question is how can I store this data in attributes in a specific class ?
Like for example, I have a class called UserDetails with attributes :
UserDetails class
public class UserDetails {
public static string RateCountry { get; set; }
public static string RateWeek { get; set; }
public int Start { get; set; }
public int Length { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
Second Class
For now, its working like this. But I want to enhance it by making use of objects.
public static string RateCountry { get; private set; }
public static string RateWeek { get; private set; }
public ActionResult ShowList()
{
int start = Convert.ToInt32(Request["start"]);
int length = Convert.ToInt32(Request["length"]);
string name = Request["search[value]"];
string address = Request[("columns[3][search][value]")];
string rateType = Request[("columns[7][search][value]")];
if (string.IsNullOrEmpty(rateType)) // if null, reset the static variables to null
{
RateCountry = "";
RateWeek = "";
}
else
{
if (CheckDate(rateType)) // if contains date, assign to RateWeek
{
RateWeek = rateType;
}
else
{
RateCountry = rateType; // else if contains a string word, assing to ratecountry
}
}
var items = AssignDetails(start, length, name, address, RateWeek, RateCountry);
return items;
}
Then instead of passing several parameters like start, length, name etc. in the method AssignDetails, I can pass an object of the UserDetails class directly taking into consideration the static variables.
Can someone please help ?
Note: In C#, they are called properties not attributes. Attributes are a totally different thing.
What you want to do is straight forward:
Firstly, you need to change your method so it accepts your class UserDetails as an argument:
public void AssignDetails(UserDetails userDetails)
{
// Use userDetails here to do whatever you want
}
Secondly, when you call the above method, you need to pass the argument to it. You can create an instance of UserDetails and pass it to the AssignDetails method:
var userDetails = new UserDetails
{
Start = start,
Length = length,
Name = name
Address = address
}
I am not sure why RateWeek, and RateCountry properties are static in your class, but to set those you can do them as below (Please note it is using the class and not the instance of the class):
UserDetails.RateWeek = RateWeek;
You could make use of the instance's properties as an indirection to the class' static properties, although all this thing is really ugly in terms of design.
public class UserDetails
{
public static string PersistedRateCountry { get; set; }
public static string PersistedRateWeek { get; set; }
public static string RateCountry
{
get { return string.IsNullOrEmpty(rateType) ? "" : PersistedRateCountry; }
set { PersistedRateCountry = value; }
}
public static string RateWeek
{
get { return string.IsNullOrEmpty(rateType) ? "" : PersistedRateWeek; }
set { PersistedRateWeek= value; }
}
public static string RateWeek { get; set; }
public int Start { get; set; }
public int Length { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
I strongly suggest you to move these static properties out to another class, which would be responsible for persisting them.
E.g. try to separate your Data Object (which just holds data) from your Business Object (which contains business logic, and is constructed by receiving a Data Object as parameter). Put all that crazy persistence logic in the Business Object, and use the Business Object everywhere in your code (instead of using the Data Object).
Keep your classes short and clean. If you are coding a lot in the same class, it's probably because you got a bad object-oriented design.
I am writing a triggerbot and I'm creating a class called settings that contain private variables (all the controls in the form) and public properties (bools and ints)
public class Settings
{
private BunifuCustomTextbox xOffsetTB;
private BunifuCustomTextbox yOffsetTB;
private BunifuCustomTextbox scanIntervalTB;
private BunifuCustomTextbox rClickIntervalTB;
private BunifuCustomTextbox snipeWatiTimeTB;
private BunifuCustomTextbox arrowWaitTimeTB;
private BunifuCheckbox closeRangeRClickCB;
private BunifuCheckbox longRangeRClickCB;
private BunifuCheckbox closeRangeLClickCB;
private BunifuCheckbox longRangeLClickCB;
private BunifuSwitch kinessaModeCB;
private BunifuSwitch shalinModeCB;
private BunifuiOSSwitch DrawCB;
private BunifuiOSSwitch DisableOnShiftCB;
public int xOffset { get; set; }
public int yOffset { get; set; }
public int scanInterval { get; set; }
public int rClickInterval { get; set; }
public int snipeWaitTime { get; set; }
public int arrowWaitTime { get; set; }
public bool closeRangeRClick { get; set; }
public bool longRangeRClick { get; set; }
public bool closeRangeLClick { get; set; }
public bool kinessaMode { get; set; }
public bool shalinMode { get; set; }
public bool draw { get; set; }
public bool disableOnShift { get; set; }
}
I'll be writing the get set statements that will get the value from the controls and set the values to the controls.
I want the program to update on the fly as the user changes the input there for I should lock either the entire Settings class or each individual property in the Settings class. Which would be the better choice in terms of performance ?
Note that I do know that I'll have to Invoke the main thread to change the values in the controls. I also know that the thread using these properties should creates it's own private copy of the variables and release the lock before trying to do anything else. My main concern is the performance and if I lock the settings class within an infinite loop with no Thread.Sleep(xx); is there a possibility that, that thread will always have the settings variable locked ? cause something similar happened while I was experimenting on another project
Performance-wise I'm pretty sure that is the same performance. When you use lock(object), you are using the reference number to create an exclusion zone, and any other lock over the same object will require the first to complete. What are you achieving with this approach, is to avoid collisions between user updating different field. Also, the possible benefits from concurrency can be added back by the overhead of having the multiple exclusion zones. Do a small experiment, timing both approachs.
I am currently developing a file indexing system. I have an interface IDiskDrive that can get immediate file items (files/folders). The interface definition is as follows...
public interface IDiskDrive
{
bool IsReady { get; }
string Name { get; }
string VolumeLabel { get; }
string VolumeLabelName { get; }
DiskDriveType Type { get; }
FolderPath RootFolder { get; }
DiskDriveUsage Usage { get; }
IEnumerable<IFileItem> GetImmediateFileItems(FolderPath path);
}
The ability to read all file/folders is complete and works correctly. Now, I need to actually index the file files and folders. Looking ahead I know I will need some reporting tools. This leads me to think I need another abstraction, based upon IDiskDrive that can read/populate. I also need the ability to select drives for indexing.
My question is should my new class inherit IDiskDrive or should I use composition (possibly a decorator)?
// inheritance
class IndexedDiskDrive : IDiskDrive
{
public IndexedDiskDrive(IDiskDrive drive)
{
...
}
public int Id {get; internal set; } // database id
public bool Selected { get; internal set; }
public DateTime? DateLastIndexed { get; internal set; }
// IDiskDrive implementation
public bool IsReady
{
get { return this.Drive.IsReady; }
}
}
or composition...
class IndexedDiskDrive
{
public IndexDiskDrive(IDiskDrive drive)
{
this.Value = drive;
}
public IDiskDrive Value
{
get;
private set;
}
// additional properties
public int Id { get; internal set; }
public bool Selected { get; internal set;}
public DateTime DateLastIndexed { get; internal set; }
}
Note:
I need access to the underlying IDiskDrive for the UI.
For example, I request user to select drives to index. I initially supply a list of local drives and the ability to add network drives. To try and keep code simple, I thought the idea of a new class with a selected property might help.
This allows the GUI to enumerate a list of IndexedDiskDrives and set/clear the select property.
In both examples you expose the IDiskDrive object from the other object. In the first case you inherit from the same inteface, which means you expose the same methods and in the other case you expose the object via a property.
I don't see a reason yet why you want to do this.
It sounds like a typical constructor DI case to me. Just have a new interface for your new class which is doing a different job and hence requires a different contract, and if it needs the IDiskDrive object as a dependency, then just inject it via the constructor and leave it as it is.
P.S.: I know this is not something you have asked, but you might be interested in Lucense.NET, which is a .NET library to index files. They might have already solved your problem for your:
http://lucenenet.apache.org/
EDIT:
From your current class design I would do the following:
void Main()
{
// Use IoC container in real app:
var diskDrive = new DiskDrive(...);
var fileIndexer = new FileIndexer();
var fileItems = diskDrive.GetImmediateFileItems(filePath);
fileIndexer.IndexFiles(fileItems);
}
// Define other methods and classes here
public interface IDiskDrive
{
bool IsReady { get; }
string Name { get; }
string VolumeLabel { get; }
string VolumeLabelName { get; }
DiskDriveType Type { get; }
FolderPath RootFolder { get; }
DiskDriveUsage Usage { get; }
IEnumerable<IFileItem> GetImmediateFileItems(FolderPath path);
}
public interface IFileIndexer
{
void IndexFiles(IEnumerable<IFileItem> files);
}
public class FileIndexer : IFileIndexer
{
public void IndexFiles(IEnumerable<IFileItem> files)
{
// do stuff
}
}
Over the past two years I developed apps for the CF .NET 3.5 to be runned on warehouse's portable device(windows mobile).
From the beginning I just jumped into the process and made a lot of mistakes that I'm gradually correcting. What has came out are apps made in this way:
a main form to start the whole process which automatically creates a data-form, that will stay alive for the whole time. This data-form will keep all the datas that the user will insert or request from the server. The other forms are basically views of the data with methods to manipulate them.
It works but...am I doing this in the right way? Or maybe am I missing something really fundamental?
So, you created a data form, and you are using it like RAM. You never display the data, you simply store it there to access.
If someone ever has to take over your job (like you leave the company or die), they are going to hate you so bad.
A better technique would be to create a Class that houses all of this data.
The good part is, since you already have a data form, you probably already know how everything is organized!
Now, just use that knowledge of your data to create your class that you can read and write to.
If you have groups of similar items, create other classes that your main class will contain.
If you have several of these similar items, create publically accessible Lists of these items.
Make it as dead simple or as complex as you'd like!
Consider these classes, which are all generic enough to modify however you would need and demonstrate some extras added:
public class DataForm {
private GroupedItem m_item2;
public event EventHandler Item2Changed;
public DataForm() { // this is your constructor
Item1 = new GroupedItem();
Item2 = new GroupedItem();
ItemCollection = new GroupCollectionItems("Group1");
}
public float Value1 { get; set; }
public float Value2 { get; set; }
public GroupedItem Item1 { get; set; }
public GroupedItem Item2 {
get { return m_item2; }
set {
if (m_item2 != value) {
m_item2 = value;
if (Item2Changed != null) {
Item2Changed(this, EventArgs.Empty); // notify whoever is listening for the change
}
}
}
}
public GroupCollectionItems ItemCollection { get; set; }
}
public class GroupedItem {
public GroupedItem() { // this is your constructor
}
public string Name { get; set; }
public object Value { get; set; }
}
public class GroupCollectionItem {
private GroupCollectionItem() { // this is your constructor
}
public static GroupCollectionItem Create(string groupName, string itemName, object itemValue) {
var item = new GroupCollectionItem() {
Group = groupName,
Name = itemName,
Value = itemValue
};
return item;
}
public string Group { get; private set; }
public string Name { get; private set; }
public object Value { get; set; }
}
public class GroupCollectionItems : List<GroupCollectionItem> {
public GroupCollectionItems(string name) { // this is your constructor
Name = name;
}
public string Name { get; private set; }
}