C# Public Static : Question about Security [duplicate] - c#

Does static variables retain their values across user sessions?
I have a ASP.NET web application where I have two buttons. One for setting the static variable value, another for Showing the static variable value.
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
public static int customerID;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ButtonSetCustomerID_Click(object sender, EventArgs e)
{
customerID = Convert.ToInt32(TextBox1.Text);
}
protected void ButtonGetCustomerID_Click(object sender, EventArgs e)
{
Label1.Text = Convert.ToString(customerID);
}
}
}
While this works in single-user environment, What happens if there are 2 users simultaneously logged in from two computers, User 1 sets the value as 100, then User 2 sets the value as 200. after that user 1 invokes the Get Value button. What will he see as the value?

Does static variables retain their values across user sessions?
Yes, that's why you should be VERY careful when you use static variables in a web app. You will run in concurrency issues as more than one thread servicing a request can modify the value of the variable.
While this works in single-user environment, What happens if there are
2 users simultaneously logged in from two computers, User 1 sets the
value as 100, then User 2 sets the value as 200. after that user 1
invokes the Get Value button. What will he see as the value?
The user will see 200 afterwards.

Static Variables Scope is Application Level.
If you store something in Static variables, definitely your doing something wrong.
If one user saves the data(In Static variable), Same time another user access same page then he will get the same data(First User saved).
So better you can store the values in **Sessions**.

This would work for you (keep in mind, you need to handle null values/-1):
public static int customerID
{
get { return session["customerID"] == null? -1 : (int)session["customerID"]; }
set { session["customerID"] = value; }
}

Do not use static for the property then it works:
public int customerID
{
get { return Session["customerID"] == null? -1 : (int)Session["customerID"]; }
set { Session["customerID"] = value; }
}

Related

How can I store static class objects for recall on any page?

I want to store static values in a class for later use use on any page in the web. The values will be the same for all users.
Page_Init: Retrieve global variables from their respective sources and assign them to their static objects inside the classes within the GlobalStaticVariables class.
I call to set the static values from the MasterPage like so
protected void Page_Init(object sender, EventArgs e)
{
Web.StartUp.SetGlobalStaticVariables(this.Page);
}
///Removed most objects for the sake of brevity
public static Info.GlobalStaticVariables SetGlobalStaticVariables(object _this)
{
Info.GlobalStaticVariables.Some_StringValue = ConfigurationManager.AppSettings["Some_StringValue"].ToString();
Info.GlobalStaticVariables.Database.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
Info.GlobalStaticVariables.IIS.DomainName = ((Page)_this).Request.Url.Host;
}
///Removed most objects for the sake of brevity
public class Info
{
public class GlobalStaticVariables
{
public static string Some_StringValue { get; set; }
public class Database
{
public static string ConnectionString { get; set; }
}
public class Ldap
{
public static List<string> ServerList { get; set; }
}
}
}
I thought that I should first see if the Session object exists, then create if it doesn't as I have read that sometimes static values can be lost due to appPool recycle, etc.
I figured I should do this from the MasterPage since I have to reference "Session" but I don't know how I would pass the Page object to a property in a class file.
I use the following in the MasterPage to store the current user so I thought that I could do a similar thing with global variables. So far I have been unsuccessful.
public MyClass.Users.CurrentUser GetSetCurrentUser
{
get
{
if (Session["CurrentUser"] == null) GetSetCurrentUser = new MyClass.Users.CurrentUser();
return (MyClass.Users.CurrentUser)Session["CurrentUser"];
}
set { Session.Add("CurrentUser", value); }
}
With the previous though, I also have to add the following to each page that wants to reference the GetSetCurrentUser property (Master.GetSetCurrentUser ), but I would prefer to avoid this if possible.
<%# MasterType VirtualPath="~/mp.Master" %>
Unfortunately when I tried the same with GlobalStaticVariables no intellisense appeared aside from .Equals, .GetHashCode, .GetType and .ToString.
I want to be able to call the property GlobalStaticVariables from any page for easy access to it's static values.
Perhaps my thought process is flawed in attempting to do it this way, but I can't think of another way. Perhaps I needs to step away from this for awhile and enjoy the holiday, but I can't, I'm on a mission. :-)
Thank-you for you time and suggestions.
You're looking for HttpApplicationState that is available in your page by Context property which holds an Application property.
How you can use it:
void Page_Load(object sender, EventArgs e)
{
var last = Context.Application["lastActivity"];
lblLastActivity.Text = last == null?"(none)": ((DateTime) last).ToString();
Context.Application["lastActivity"] = DateTime.Now;
}
One other option is the use of Cache which works similar but objects stored in the Cache can get removed from the cache (to free memory). You should be able to reload the objects in that case though.

replacement for static variable

I am developing an ASP.NET MVC 4 application. userMenus is a static variable that is loaded every time a user logs in.
public class MenuCL
{
public static List<UserMenu> userMenus = new List<UserMenu>(); // the static variable
}
public class UserMenu
{
public decimal MenuID { get; set; }
public string MenuName { get; set; }
public string Controller { get; set; }
public bool Permission { get; set; }
}
I use that static variable to check whether or not the logged in user has permission to a menu/controller in a custom authorize filter.
It works fine when a single user is logged in, but when two or more users are logged-in, it's all messed up, I mean the error page("you don't have access to this page") is displayed to a user that has permission to the menu/controller.
Only now I realized it's the static variable that is causing all the trouble, after I read this :
The static variables will be shared between requests. Moreover they will be initialized when application starts, so if the AppDomain, thus application gets restarted, their values will be reinitialized.
So I need a replacement for this static variable. Anyone has any suggestion?
You can still use a static field which is a property that provides access to a session variable.
public static List<UserMenu> UserMenus
{
set
{
Session["UserMenus"] = value;
}
get
{
return Session["UserMenus"] == null ? new List<UserMenu>() : (List<UserMenu>) Session["UserMenus"];
}
}
In order to get this working on a web farm which uses a session state server (or sql server), you need to put [Serializable] attribute on top of UserMenu.
I don't think, this way you need to modify your code very much.
My question is, why do you want to use static variable? Do you want to share the values across the application? In this case you can better use session.
Updated
Assume lst as a non static List of UserMenu. Then you can use the following method to store it in session and get it bak whenever you want.
To store
Session["usemenulist"] = lst;
To get it back
try
{
lst = (List<UserMenu>)Session["usemenulist"];
}
catch
{
}
Note
If you are getting the values from the database lo load it to the List for the first time, then you can query database to get it from the database whenever you want, instead of storing it in the session. (This is another option apart from Session, you may try this way also if you want.)

Using values from one aspx.cs file to another aspx.cs file with a common class

common class file common.cs: This file, I have added by clicking add->new items-> class
public class common
{
public int v,n;
public int da()
{
return n= v;
}
}
Another file: It's an webpage file name is a1.aspx.cs:
common c = new common();
c.v = Convert.ToInt32(TextBox1.Text);
c.da();
Response.Redirect("ulogin.aspx");
the value from a text box stores in c.v variable
So, now, I want the value which was given in the textbox1.text in another webpage file named as ulogin.aspx.cs
I used this code:
common d=new common();
d.da();
Label1.Text = Convert.ToString(d.n);
but after running it shows the value as 0.....
In a web application, you'll need to persist the information somewhere common (typically Session for per user info or Application for per application info) so that it can be used between different pages & user controls in your application.
I'd suggest adding a Session backed property to your page & usercontrol which accesses a common Session["variable"]. Something like the following.
(i.e. lets imagine your code was being exectued on a button click)
a1.aspx.cs
public int ValueToStore
{
get
{
return Session["ValueToStore"] != null
? (int)Session["ValueToStore"]
: 0
}
set
{
Session["ValueToStore"] = value;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
ValueToStore = Convert.ToInt32(TextBox1.Text);
Response.Redirect("ulogin.aspx");
}
ulogin.aspx.cs
public int ValueToStore
{
get
{
return Session["ValueToStore"] != null
? (int)Session["ValueToStore"]
: 0
}
set
{
Session["ValueToStore"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = ValueToStore.ToString();
}
As you can see, you now have some code duplication between the two pages, so the next step would be to consider implementing a basepage which as the common property, and then inherit that from a1.aspx & ulogin.aspx.
i.e.
public class a1 : BasePage
{
...
}
public class ulogin : BasePage
{
...
}
public class BasePage : System.Web.Page
{
//Put ValueToStore property here.
}
There are many users visiting same page, they may set different value, and the expected result is whatever value is set by an user on Page 1 need to be displayed in Page 2.
Any Web technology is stateless as they use HTTP which is stateless again.
However there are many ways to get this done, each method has their own advantages.
--Session--
Please use session variable to store your value, which is a kind of variable.
Each user has different session variable to store, and its available
Until the user logs out (i.e. till Session is available)
Storage: Server Memory
public class Common
{
public int? Data
{
get
{
if(Session["Data"]!=null)
{
return int.Parse(Session["Data"].ToString());
}
return null.
}
set
{
Session["Data"]=value;
}
}
}
--Query String--
You can pass value from one page to another page using query string.
Page 1
int value=1;
Response.Redirect("Page2.aspx?data="+value.ToString())
Page 2
if(!string.IsNullOrEmpty(Request["data"]))
{
int value=int.Parse(Request["data"]);
}
--Posting--
You can also post the value from one page to another page.
Page 1 (html)
<form action="page2.aspx" method="post">
<input type="hidden" name="data" value="1"/>
</form>
Page 2
if(!string.IsNullOrEmpty(Request["data"]))
{
int value=int.Parse(Request["data"]);
}
There are even more ways... You have to select what is suitable for your scenario.
Read ASP.NET State management
http://msdn.microsoft.com/en-us/library/75x4ha6s.aspx
If the page ulogin.aspx is designed to be always redirected from a1.aspx, then set the PreviousPageType in ulogin.aspx and get the previous page values by this.PreviousPage instance. (Cross-Page-PostBack)
Convert member v to a property of common. Store common into a Session variable. And once you are ready to get the value, cast session variable to common and access v property from there.

How to define a global variable in ASP.net web app

I have face a requirement,
I want client access a data center but without use database , so I want my web app can retain a global or Application session variable, that contains the data, every client can access the same data... I am try to declare in golabl, but seem it only can store String but others ...
how to solve this problem ?
thanks.
Another option of defining a global variable is by creating a static class with a static property:
public static class GlobalVariables
{
public static string MyGlobalVariable { get; set; }
}
You can make this more complex if you are going to use this as a data store, but the same idea goes. Say, you have a dictionary to store your global data, you could do something like this:
public static class GlobalData
{
private static readonly object _syncRoot = new object();
private static Dictionary<string, int> _data;
public static int GetItemsByTag(string tag)
{
lock (_syncRoot)
{
if (_data == null)
_data = LoadItemsByTag();
return _data[tag];
}
}
private static Dictionary<string, int> LoadItemsByTag()
{
var result = new Dictionary<string, int>();
// Load the data from e.g. an XML file into the result object.
return result;
}
}
To Share the data with all application users, you can use ASP.NET Application object. Given is the sample code to access Application object in ASP.NET:
Hashtable htblGlobalValues = null;
if (Application["GlobalValueKey"] != null)
{
htblGlobalValues = Application["GlobalValueKey"] as Hashtable;
}
else
{
htblGlobalValues = new Hashtable();
}
htblGlobalValues.Add("Key1", "Value1");
htblGlobalValues.Add("Key2", "Value2");
this.Application["GlobalValueKey"] = htblGlobalValues;
Application["GlobalValueKey"] can be used anywhere in the whole application by any user. It will be common to all application users.
You can stuff data into the Application object if you want. It isn't persistent across application instances, but that may sufficient.
(I'm not for a minute going to suggest this is a best practice, but without a clearer picture of the requirements, that's all I can suggest.)
http://msdn.microsoft.com/en-us/library/system.web.ui.page.application.aspx
http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx
If you are using WebApplication or MVC just go to Global.asax (in WebSite project you need to add Global.asax from the add new item menu).
I will explain to deploy two global variables for your web application:
Open the Global.asax file, then define your variable in Application_Start function as following:
void Application_Start(object sender, EventArgs e)
{
Application.Lock();
Application["variable1"] = "Some Value for variable1";
Application["variable2"] = "Some Value for variable2";
Application.UnLock();
}
If you want to use that those global variables in aspx pages just need to call them like this:
<p>I want to call variable1 <%=Application["variable1"].ToString() %></p>
<p>I want to call variable1 <%=Application["variable2"].ToString() %></p>
But if you want to use that those global variables in server-side call'em like this:
protected void Page_Load(object sender, EventArgs e)
{
string str1 = Application["variable1"].ToString();
string str2 = Application["variable2"].ToString();
}
Note: You must be aware that these global variables are public to all users and aren't suitable for authentication jobs.
You can also use Cache, which has advantages like ability to set expire time/date.

ASP.NET Web Page Postback

I have a class level price variable decalred inside a page, like this:
public partial class _Default : System.Web.UI.Page
{
private MyClass myVar = new MyClass();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
myVar.LoadData();
myVar.ShowData();
}
}
protected void cmdRefresh_Click(object sender, EventArgs e)
{
myVar.ShowData();
}
}
The problem I have is that after the initial load, the first time that the button is pressed it seems to reset myVar, and all its data is lost. Is this a known issue with ASP.NET and is there a workaround?
Use the ViewState to store the class, if you just need to save the classfor the current page. IF you want to save it for the entire site, then look into things like Sessions.
private MyClass myClass
{
get {
if (this.ViewState["myVar"] != null)
{
return (MyClass)this.ViewState["myVar"];
}
}
set{
this.ViewState["myVar"] = value;
}
}
The variable myVar will never be persisted across postbacks, you need to use some method of caching, such as Application / Session / ViewState / Cookies.
Yes that is a know functionality. Basically you page object is created for every request, so properties are set for you (IsPostBack being one of them) but you need to take steps you self to make sure that fields (declared in code) is populated every time. In this particular case either by fetching Them or keeping Them in the form (viewstate) or session data. Which one to choose should depend on such as size of data, time to refetch, data store loads etc.

Categories

Resources