Strange behavior of static variables in a web site - c#

I prepared a very simple Web site to demonstrate this behavior.
It has one page with one Button and the following code:
public partial class TestStatic : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Class1.SetValue();
Label1.Text = Class1.st.ToString();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = Class1.st.ToString();
}
}
and one class:
public class Class1
{
public Class1()
{
}
public static int st = 0;
public static void SetValue()
{
st = 1;
}
}
So when the page is loaded you see in Label1 that st=1. If user clicks on the Buttton that sometimes you can see st=0 and sometimes st=1. In debugging I see that sometimes command
public static int st = 0;
is executed when an user clicks on the Button and this is a reason why st is changed to zero. This behavior I can reproduce in framework 4.5 only: it does not occur in framework 3.5. Can somebody explain me such behavior?

Static data lives per application domain instance. Since the hosting (IIS) can unload application domains between web site calls, static data can be lost.
So, you really shouldn't rely on static in web apps.

static values are shared across all instances of a class inside of a single App Domain.
If you're using IIS Express, your appdomain may be getting recycled more often than you think it is.
reference this: Lifetime of ASP.NET Static Variable

Related

Winform C# Read and execute source code from server

I have a winform app, I completed with business model and update function. But when I learn about security .Net, I found that almost impossible to anti crack/hacking with obfuscation.
So I want move 99.99% source code to cloud. But I've not found any doc that useful for making it.
Can I do my idea as below:
using ....;
namespace myApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public GetSourceClass()
{
// Here i want get all source code, include all class and all
// variables from server.Is it possible?
}
private void Form1_Load(object sender, EventArgs e)
{
GetSourceClass();
}

Accessing context session variables in c#

I have an ASP.NET application and dll which extends IHttpModule. I have used the below method to save the session variables in httpcontext through
public class Handler : IHttpModule,IRequiresSessionState
{
public void Init(HttpApplication httpApp)
{
httpApp.PreRequestHandlerExecute += new EventHandler(PreRequestHandlerExecute);
}
public void PreRequestHandlerExecute(object sender, EventArgs e)
{
var context = ((HttpApplication)sender).Context;
context.Session["myvariable"] = "Gowtham";
}
}
and in my asp.net Default.aspx page I have used code to retrive value as
public partial class _Default : System.Web.UI.Page, IRequiresSessionState
{
protected void Page_Load(object sender, EventArgs e)
{
String token = Context.Session["myvariable"].ToString();
}
}
I am getting error response as
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
In order to ensure whether the variables store in session I have crossed check by following method in class handler after storing the value in session as
string ss = context.Session["myvariable"].ToString();
it well executed and retrieved the value from session.
Why do you need to use Context and not Session directly? From the code I can only assume that you are going to set a value in the Session, and then read the value on page load. Rather than you do something like that, you can do this:
Add a Global Application Class, Right click on your project, Add > New Item, choose Global Application Class, and on that file, insert the following code to initialize the value
protected void Session_Start(object sender, EventArgs e)
{
Session["myvariable"] = "Gowtham";
}
On the Page_Load, you can access by:
if ( Session["myvariable"] != null ) {
String token = Context.Session["myvariable"].ToString();
}
Hope this help..
use System.Web.HttpContext.Current.Session["myvariable"] in both parts

Windows Phone 7 Silverlight using session

I am creating a Windows 7 mobile Silverlight project. I use Rest api for authentication using a class say Authentication. I get an authentication token as a response and I assign it to a class property AuthToken because I need to use this in different places. Is there any way to store this AuthToken in session or any thing else. Because I did not find any session example in wp7. Thanks
If you want temporary session storage (the life of the app including when a user uses the back button to return to your app) then you can use Phone State. The Phone State is similar to Session State in ASP.NET. It is just a dictionary of (serializable) objects with string keys and is not maintained across launches of your app, but it is restored when your app is navigated to from the Back Stack.
Here is an example of it's use to restore some custom object named myObject:
private CustomObject myObject;
protected override void OnNavigatedFrom(NavigationEventArgs args)
{
//Save to State when leaving the page
PhoneApplicationService.Current.State["myObject"] = myObject;
base.OnNavigatedFrom(args);
}
protected override void OnNavigatedTo(NavigationEventArgs args)
{
if (PhoneApplicationService.Current.State.ContainsKey("myObject"))
{
//Restore from State
myObject = (CustomObject)PhoneApplicationService.Current.State["myObject"];
}
else
{
//No previous object, so perform initialization
myObject = new myObject();
}
}
If you need to store settings across all instances of your app then look into IsolatedStorageSettings which is perfect for this. There are other options depending on your needs (Charles Petzold has a free eBook with some great examples).
Not sure why the above code didn't work for you, but another option is to use an app property which is saved using IsolatedStorageSettings. Here is an example:
In your App.xaml.cs:
public bool VibrationOn { get; set; }
private void Application_Launching(object sender, LaunchingEventArgs e)
{
LoadSettings();
}
private void Application_Activated(object sender, ActivatedEventArgs e)
{
LoadSettings();
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
SaveSettings();
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
SaveSettings();
}
private void LoadSettings()
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
bool vo;
if (settings.TryGetValue<bool>("VibrationOn", out vo))
VibrationOn = vo;
else
VibrationOn = true;
}
private void SaveSettings()
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
settings["VibrationOn"] = VibrationOn;
}
You can then access this property anywhere in your application by using this code:
if (Application.Current.VibrationOn)
{
VibrateController.Default.Start(TimeSpan.FromMilliseconds(200));
}
You're not finding any session examples because WP7 doesn't have session as far as I know. You should be able to use Isolated Storage to keep your AuthToken around. Bear in mind, however, that it wont expire after a certain amount of time like you'd expect with a session.
See the following or google search Isolated Storage for examples:
http://www.windowsphonegeek.com/tips/all-about-wp7-isolated-storage-store-data-in-isolatedstoragesettings
Hope it helps. I haven't done a great deal of WP7 development, but I'm familiar with Silverlight.
Assuming you only want it for the lifetime of the current application instance:
The simplest answer is to store it as a static property instead of an instance property.
The simple answer is to store it as a property of your Application class (App.xaml.cs). Then you can access it anywhere using ((App)(Application.Current)).Token
The less simple, but probably better answer would be store it in a ViewModel property, which you could then access via a ViewModel locator - take a look at MVVM Light for examples.
In all of these cases you'll need to take into account Tombstoning, to restore it if the user hits Start and then Back (for example).

Update UpdatePanel on different user’s web page

I have a web page (aspx). This page has a button , a UpdatePanel and a Timer. Now my problem is as follow suppose 10 users are on this page at the same time and suppose user number 3 and 8 click its button then all user’s UpdatePanel should get updated. What is right way to achieve this functionality?
Since each user is running its own copy of the web application so whats happenning on one user's browser can't be notified to the other user. One thing you could do is when one user clicks the button to update, you could save it, whereas all the user application could ping the server may be every 2 secs to know if updation happens and if so updates.
You could use a Global property. On that property, you can put an Observer pattern, and let the visitors subscribe. When you alter the Application property ( shared throughout all Sessions ), you call the Notify() method. The client Notify() method gets called, and there you put functionality to update the UpdatePanel.
This code is NOT TESTED, it is a guideline
// *** GLOBAL.ASAX
// This collection will contain all the updatepanels that need to be updated
private List<IUpdatePanelClient> _registeredClients = new List<IUpdatePanelClient>();
public static void RegisterClient(IUpdatePanelClient client)
{
_registeredClients.Add(client);
}
public static void UnregisterClient(IUpdatePanelClient client)
{
_registeredClients.Remove(client);
}
// Which client is triggering the update call ?
private IUpdatePanelClient _clientUpdating = null;
public static IUpdatePanelClient ClientUpdating
{
get { return _clientUpdating ; }
set { _clientUpdating = value; Notify(); }
}
// Notify the clients
public static void Notify()
{
foreach(IUpdatePanelClient client in _registeredClients)
{
client.Update();
}
}
// *** IUPdatePanelClient.CS
interface IUpdatePanelClient // Interface to make the calls
{
void Update();
}
// *** Your codepage
public class MyUpdatePanelPage : Page, IUpdatePanelClient // Inherit the interface
{
public void Page_Load(Object sender, EventArgs e)
{
MyUpdatePanelPage.Global.RegisterClient(this);
}
public void Btn_Click(Object sender, EventArgs e)
{
MyUpdatePanelPage.Global.ClientUpdating = this;
}
public void Update()
{
this._updatePanel1.Update();
}
}
Your question doesn't have enough information for anyone to answer properly. If there is information that you want to keep all users update-to-date on, store that information in a database. When one user edits the data from their user session, whenever other user's get their page refreshed, they will have the most updated data. If you want to have their page refreshed periodically, use a javascript timer.

Session Variables, Web Services, ASP.NET, and C#

I'm having an issue with ASP.NET's session variables and a web service proxy object. I can access any data I create inside the actual .asmx file, but adding data "Through" the session variable results in absolutely nothing happening.
My goal is quite simple, I want to create an "Almost Shopping cart". The customer enters a title into this text box, and it's sent to the Web Service. The web service is called in the masterpage, and it grabs an array list full of the "titles" that the customer is requesting.
The data is visible in a drop down box, and a label that stores the total cost of all the items (I'm not worried about the cost at the moment).
The issue is, anytime I call a web service method, absolutely nothing happens.
The Code in question:
Basket.asmx
public class basket : System.Web.Services.WebService {
ArrayList reservations = new ArrayList();
double total = 0;
public basket()
{
reservations.Add("Extreme Test Data");
reservations.Add("Moar Test Data");
}
[WebMethod]
public string[] getReservations()
{
//This may be part of the issue, still not sure.
return (string[])reservations.ToArray(typeof( string));
}
[WebMethod]
public string toString()
{
return reservations[reservations.Count - 1].ToString();
}
[WebMethod]
public double getTotal()
{
return total;
}
[WebMethod]
public void addCost(double price)
{
total = total + price;
}
[WebMethod]
public void addReservation(String title)
{
reservations.Add(title);
}
[WebMethod]
public void removeReservation(string title)
{
}
[WebMethod]
public int getLength()
{
return reservations.Count;
}
Global.asax
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
localhost.basket proxy = new localhost.basket();
Session["reservations"] = proxy;
}
(Everything else in global.asax is default)
Masterpage
This is the only relevant code in the masterpage, It calls the web service through the session variable.
protected void Page_Load(object sender, EventArgs e)
{
localhost.basket proxy = (localhost.basket)Session["reservations"];
lblTotal.Text = proxy.getTotal().ToString("c");
string[] res = proxy.getReservations();
ddReservations.DataSource = res;
ddReservations.DataBind();
proxy.addReservation("Half Life 2");
}
Reservations.aspx
This page submits the actual "new" data to the web service. I've cut out a lot of this (It's a group project, so there's a lot of code I didn't write).
protected void Page_Load(object sender, EventArgs e)
{
proxy = (localhost.basket)Session["reservations"];
Response.Write(proxy.toString() + "Count: " + proxy.getLength());
}
protected void cmdSubmit_Click(object sender, EventArgs e)
{
proxy.addReservation(txtGameTitle.Text);
proxy.addCost(39.99);
}
What does work: The default test values I entered in the ASMX, they load fine into the textbox.
So in short, can I use a web service proxy object in a session variable? If not, whats the best way to "share" this object?
Also: I'm using VS2005.
Thanks for any help!
Every web service call occurs on a different instance of the web service class. Your reservations variable cannot be used to maintain state between calls, since it's an instance variable.
You're better off making your service be stateless. However, for a case like this, you should store the shopping cart into a database. That way, the cart won't be lost on a system failure.

Categories

Resources