Session Variables, Web Services, ASP.NET, and C# - 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.

Related

Regarding Web Services C# ho to pass argument from input

I want to figure out how can I pass value from input to web services using c#? I have code:
Animal.aspx:
<div class="form-group">
<asp:Label ID="LabelForType" runat="server" Text="Animal Type"></asp:Label>
<asp:TextBox ID="AnimalType" runat="server" CssClass="form-control" Text="Animal Type"></asp:TextBox>
</div>
Animal.aspx.cs:
protected void AddAnimal_Click(object sender, EventArgs e)
{
ClientService service = new ClientService();
service.getAnimalType();
}
public String getAnimalType()
{
return AnimalType.Text.ToString();
}
Web services. ClientService.asmx.cs
[WebMethod]
public String getAnimalType()
{
return animal.getAnimalType();
}
Unfortunately it does not work. If I send my input value as a parameter to a web service. I can type whatever in soap window but it will not return the value which I typed in input. Any ideas? Or maybe there is a tutorial? Thank you.
I am looking how to pass the value from textbox ID="AnimalType" to WebServices. If type Chicken it should pass chicken to web services.
Basically. Create value - > Send it from C# as a parameter to Web Services - > Took that value in Java by calling to Web Services.
I made like.
private String type;
public void setAnimalType(String typee)
{
type = typee;
}
[WebMethod]
public String getAnimalType()
{
return type;
}
But it returns null.
This isn't doing what you think:
private String type;
public void setAnimalType(String typee)
{
type = typee;
}
[WebMethod]
public String getAnimalType()
{
return type;
}
It makes all the sense in the world from a strictly object-oriented point of view. However, when you're in the context of ASP.NET there are some subtleties of the framework and the stateless nature of HTTP which change things.
In short, every time you invoke your ASP.NET "page", a new instance of that page's class is created. So any class-level values you set on previous instances are gone.
You need to persist that value somewhere. There are many options:
A static variable
Session state
A cache somewhere
A database
A file
etc.
The ASP.NET page objects are stateless. With every request an instance is created, interacted with, and destroyed. Values which need to persist across multiple requests need to be persisted outside class-level instance members in this case.
Change you service method to take parameters as follow
[WebMethod]
public String getAnimalType(string animal)
{
//Do something with the param
return "something";
}
Then call your service like
ClientService service = new ClientService();
var animalType = service.getAnimalType(AnimalType.Text);

ASP.NET how to use Sessions, when and where to declare it?

I am trying to retrieve some data from db and store it some Session variable in order to have it in _Layout.cshtml on all pages, no matter what page the user will access from the start.
Global.asax:
protected void Application_Start()
{
...
Manager mng = new Manager();
HttpContext.Current.Session["company-cellphone"] = mng.GetContacts().CompanyCellphone;
}
Error: Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
you are trying to access the session from Application_Start but there is no live Session yet.
session is not available in all events of global.asax
as a workaround try this:
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
{
HttpContext context = HttpContext.Current;
...
Manager mng = new Manager();
HttpContext.Current.Session["company-cellphone"] = mng.GetContacts().CompanyCellphone;
}
}
I'm not sure about your requirement but I would recommend to access the session in controller.initialize method
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
//// access session here
requestContext.HttpContext.Session["company-cellphone"]=mng.GetContacts().CompanyCellphone;
}
Application_Start runs before any sessions can be created. And a session is specific to a single client connecting to your application.
You can create a static class and store the company-cellphone value in it.
In your Models folder create a new class file named Global.cs in that file create a static class with properties that will hold your application level information.
public static class Global
{
static string companyCellPhone;
public static string companyCellPhone
{
get
{
return this.companyCellPhone;
}
set
{
this.companyCellPhone= value;
}
}
Then your Application_Start method would look something like this:
protected void Application_Start()
{
...
Manager mng = new Manager();
Global.companyCellPhone = mng.GetContacts().CompanyCellphone;
}
I'm going to go out on a limb and guess that this is a single global value to be viewed by all users. In that case you could store the value in HttpApplicationState rather than HttpSessionState:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Application["YourValue"] = "SomeValue";
}
}
I'm not necessarily advocating its use. But just as Session can store user-specific values, Application stores values that are global to the application.

Strange behavior of static variables in a web site

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

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.

Categories

Resources