I'm currently working on a web app/game using C# and ASP.NET(3.5). However, I'm running into a problem of variables used in the main page being reset to null whenever I click a button on the web form. I'm wondering if there was a way to allow to variables to persist for the life cycle of the entire application, as well as for the variables to be accessed from wherever/whenever.
Another issue I'm having at the moment is that I can't seem to find a way to update the properties of controls, like text or colour, without having to refresh the page. Is there a way to update these properties "silently" without forcing the user to go through the whole page refresh cycle?
Thanks
Use Session collection to persist for a particular user. Alternatively use static variables to keep their values for the lifetime of the application domain (for all site users until the web server restarts or crashes).
To update page portions "silently" wrap them into UpdatePanels (Microsoft AJAX library thing) or use JavaScript (you can use some JS library like jQuery to make it easier and handle the cross-browser compatibility for you) to manipulale the structure of your document on-the-fly.
It really depends on the purpose of the variables, and their scope.
For variables that are different for each visitor, you want to place those variable into session.
For variables that are global to your whole app, and are the same for every visitor, then you can either use static variables, or put them into web.config as Application Settings
Changing text/color on the client, this sounds like you might need to make use of some javascript. JQuery is a javascript library that makes a lot of those type of manipulations easier.
You might have ViewState disabled at Page Level (or application level).
Usually ASP.NET stores the state of each control within the current page in the Viewstate Object to preserve their status over reloads. Have a look at the EnableViewState object in your code (Front End) or dig into the web.config.
If you also want data to persist at page level, use the Session object and work around the timeout property to find a suitable value that will work for you and your users. SlidingExpirationg could also be useful. If you are going to use this solution you might also ask yourself some questions. Is your application using 1 single server or is likely to be deployed to a server farm? If so, consider using SQL Session State instead of InProc as it will provide a more consistent "centric" place to stored the session data consumed by different servers.
Regarding updating controls without a page refresh you are looking for something called Ajax. Microsoft has release ASP.NET Ajax Toolkit, have a look at it, especially the asp:UpdatePanel which will let you "partial update" pieces of the page without reload everything else.
It's the easiest, straight forward, way to update controls properties without much effort.
Additionally, to update the client side objects without a postback to the server, you'll need to use javascript. jQuery will probably be your best bet.
Related
I'm currently on a project where each .aspx page is made up of multiple user controls (.ascx files). In some cases, more than one user control for a single page is making a call to the database for the same data. Two user controls might call the database for the same customer object to perform the tasks necessary to their individual circumstances. After all is said and done, some of the web pages end up making the same database calls 10 or more times because each user control needs the data for something it is doing. This does not seem efficient.
What are the best practices for handling this situation using ASP.NET Webforms? We have tried caching the database calls, but it just doesn't feel like a solid solution to the problem, although it has helped with performance. When using MVC, I can pass in a strongly-typed object containing all the data needed for a particular page, and the query for the data is only made one time. How do I achieve something similar using WebForms?
The best practices are the same as for any OO programming: Don't Repeat Yourself.
In this case, rather than having the user controls query the database to get their data, have the data passed to the controls, through properties. You can even use data binding, just like a "real" server control.
BTW, there's nothing at all preventing you from passing a strongly-typed object to the user controls, just like you would in MVC:
In MyControl.ascx.cs:
public MyControlModel Model {get; set;}
Then just have the calling page set Model before the control data binds.
I'm making a simple asp.net app that displays data which can be filtered based on a few different parameters. As such, the different filters that are currently selected need to be saved somewhere. I'm fairly new to .NET, and am wondering the best way to save this information. I noticed a coworker used Request.QueryString in conjunction with the Sessions dictionary. Something like this on page load:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["Category"] != null &&
Request.QueryString["Value"] != null)
{
string Category = Request.QueryString["Category"];
string CategoryValue = Request.QueryString["Value"];
// selectedFacets is the server side dictionary
selectedFacets.Add(Category, CategoryValue);
}
}
The QueryString here is changed when the user presses a button on the webpage, updating the URL.
My question is why even bother with the QueryString at all when all we're using it for is saving a value server side anyway? Wouldn't just making the button an asp controller be easier, something like:
protected void exampleCatexampleVal_Button_onClick(object sender, EventArgs e)
{
selectedFacets.Add(exampleCat, exampleVal);
}
Similar business goes on the with the Sessions dictionary: it's just used to save a bunch of values to variables on the server, so why use it in the first place? I'm sure there's a good reason, but right now they just seems overly complicated for what they do. Thank you!
Based on your code examples, I understand that you're talking about ASP.NET WebForms.
Your use case is not complete, but I'll show here some alternatives to achieve your goal. If you give further information, I'll gladly update my answer.
Before we get to it, let me just put things clear: HTTP is stateless. Understanding this basic rule is very important. It means that your server will receive a request, send it to your app (and the .NET process), get the resulting page (and assets) and send it back to the client (mostly, a browser). End of story.
(Almost) Everything that you've created to respond to the request will be lost. And that's why we have options on where to store objects/values across requests.
Server-side Session
This is one of the easiest options. You simply call this.Session.Add("key", object) and it's done. Let's dig into it:
It will use server resources. That is, the most you use the session, the most memory (and other resources, as needed) your app will consume.
It will be harder to scale, because data will be on your server memory. Vertical scale may be an option, according to your hardware, but horizontal scale will be limited. You can use a session-server or store session on a SQL Server database, but it won't be so efficient anymore.
It's attached to your client session. It will be lost if the user opens another browser or sends a link to his friend.
It's relatively safe. I say relatively because of the options below. At least it's server side.
GET arguments (AKA QueryString)
That's another option, and you know it already. You can send data back and forth using the querystring (?that=stuff&on=the&URL=youKnow).
It's limited to 2000 characters and that must be serializable. That's why you probably won't put a DataGrid there.
The user may change it. Be aware! Always sanitize data from the QueryString.
User is free to bookmark the link or send it to a friend and stuff will be the same. That's nice, mind you.
ViewState
You may have heard about it, it's the engine that makes WebForms so lovely (and so hateful). By default, each controller on your page will have its state serialized to the viewstate, which is a huge hidden field with encrypted data on your page. Go on, click "View source" and look for it. Don't scream, please. You may add arbitrary data to the ViewState just like the Session.
It's on the client side. Don't trust it.
It will be send back and forth on each request, so it will consume extra bandwidth.
It will take time to be deserialized/serialized on each request/response.
Data must be serializable (you know what I mean).
So, by now I hope that you have enough information to make your own decision.
If I missed anything, please let me know.
Have a look at this MSDN Article first. I read through it, and it may answer your question for you.
http://msdn.microsoft.com/en-us/magazine/cc300437.aspx
What you're missing, is how the asp.net page lifecycle works:
http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx
The thing is, that 'server variable' won't persist between postbacks (AFAIK). It's only useful inside that page, right then. As soon as the page is disposed at the end of the cycle, that dictionary is gone. So you have to store it somewhere if you want to use it later. The article I referenced shows you all the places that you can store information to persist it and where you store it depends on how long you need it to persist, and how many users should have access to it.
Now, certainly, if you DON'T want to persist that dictionary, then sure, just store it the page variable. That's just fine. There's no reason to persist data that you never need again.
It's always good to keep in mind that there is a slight performance hit when storing and retrieving session state from database or from separate process service (StateServer). If session state is stored in-memory, you cannot scale your application to a web farm and this wastes valueable memory in the web server.
On the other hand, using query string values won't waste your memory and resources, it is fast and you don't have to think about managing session state. It gives SEO benefit and allows bookmarks/favorites.
However, you can store only limited amount of data using query string (WWW FAQs: What is the maximum length of a URL). It can also pose a security risk, if sensitive data is exposed or a malicious user tries to find a bug in your code that mishandles URL values. SQL injection attack is one scenario. What you can do is encrypt sensitive values.
Overall there are many aspects to consider here.
One of the benefits of using query string values is if you need bookmarks/favorites stored in your application that would allow a user to directly navigate to a page and have certain values be passed into the page without the assistance of an in-memory cache. Take the following for example:
I have a product page that displays a grid view of products that can be filtered by a category name. If I use the categoryId value in the query string, then I can make a bookmark to this page and then later click on the bookmark and the page will work as I left it earlier. Depending upon in-memory cache, that may or may not be there, would not guarantee that my bookmark would work every time.
I'm currently working on a web application that has a lot of user settings.
Things that can be displayed, graphics, statistics, coloring etc.
For example a setting would be something like (ItemID = 1, MyCutOff = $5.00, AlertColor=Red)
There are a lot of these different types of settings some more complicated than others.
Right now what I'm doing is on Login the users settings are read and stored in a DataTable which is stored in session, but I'm sure that is not best practice.
What is the best practice to deal with this ? I'd like to be as efficient as possible since the application has the possibility of having many concurrent users.
Thanks.
If you use database to hold your session, then you read them from one table and you move them to some other table.
For me you can left them on the DataTable that you already have them and just ask for them when you need them.
Now one optimization that you can do in a page cycle is to use the HttpContext.Current.Items[], for example if you load a parameter from your table and you need to use it on 20 different place in a page call (eg, inside custom controls, inside the master page, inside the page etc) you can use the HttpContext.Current.Items[] to store it.
There are also the asp.net profile properties that can be customized and used for your users.
If they are truly just settings ( things that determine the UI etc) you could also use localStorage. Really easy to stringify and parse json data in key value pairs using localStorage. As long as its not sensitive data. If you need to pass the params back server side this may not always be the best option but that's for you to decide as you know the project but may be worth a look.
I have in the past always had quite a few problems maintaining the session state with WebMatrix, and handling them when expecting them to be timed-out (mainly because I am still learning).
The user input must always be remembered, because if they submit and a custom error occurs, I don't want them to have to re-input all of the information back into the form.
I think I have a method figured out (finally) that can properly maintain and manage timed-out session variables in the future, when they are needed.
I realize that there are several other methods of transferring data between web pages, and believe me, when applicable, they will certainly be used first. This question only pertains to when I feel like the session variable is my best option.
My problem is, I always think I have it figured out, and then, only after I have set up over half of the coding, do I realize why it doesn't quite work, and then find some sloppy (but effective) work around that will at least work for that project.
The projects I will use session variables in use the common database with web interface combination. Usually there are 3 main pages: an add entry page, an edit entry page, and a lookup entry page. The add entry page and the lookup entry page eventually post and redirect to the edit entry page.
Before I begin my next project, I thought it would be wise to inquire if my method is at least aiming in the right direction, or if I am still not approaching this quite right.
Here is what I think might work (although, it seems a bit too easy):
Use local variables per page.
In an (IsPost) branch assign the session variables based off of the local variables just before posting/redirecting.
On the other page, just after being redirected, use the session variables to assign new static local variables.
In other words: I will (when necessary) use the session variables only to transfer the data which will happen in a completely acceptable amount of time (not allowing the session state enough time to timeout), and then referring only to the local variables when needed, per page.
Am I crazy or is this the best way (or at least a decently viable way) to handle this, when forced to work with the session state in WebMatrix?
Sorry if this is a stupid question xD
In my opinion, you should not use Session variables to remember what the user entered into the form. The form - add or edit - should post to itself for validation. That way, the values are available in the Request.Form collection. You can easily repopulate the form in the event of a validation error. On successful submission, you insert or update the database, and then redirect to another page to prevent duplicate submission.
Session variables are really easy to use if used appropriately. I suspect your difficulties arise because you are using them for the wrong scenarios.
I'm designing a web application that has to pass sensitive information (like the user's account number) from page to page until the user is done (the application is like a wizard), for logging purposes. What is the best way of storing this data so that each page in the process can get access to the data? Should I be storing it in the session? In the database, then delete it at the end? Some method I haven't thought of yet?
I personally try to avoid using the session where possible. Here are the options that I know of when dealing with wizard type scenarios:
Option 1
Use JQuery as discussed in Nadeem Afana's blog. The pages are displayed to the user one by one but the information is not submitted until the final page.
Option 2
Is the information on every page sensitive? Could it be structured so that the sensitive information is just asked for on the final page? If so you could serialize data across the pages as discussed in Darin Dimitrovs answer and just not provide a back button on the final page. Alternatively, the data that is serialized can be encrytped with ease using the same MVC Futures serialization software although i'm not sure how sensitive your information is and whether you would want to rely on this. The answer also mentions alternatives such as Stepy but I have no experience with this.
Option 3
If the information is sensitive you could write/read the information to a database between requests.
Option 4
Finally, if you can't use any of the above then I would use the Session or TempData (which is a wrapper around the session) but beware that with TempData, if the user refreshes the page then the information will be lost.
Session sounds fine to me, it goes away (almost) automatically.
If you are paranoid then you can encrypt it or store it somewhere else and find it through a hash. This "somewhere else" is then your next point of save-enough-?
Just make sure it doesn't reach the web client.