Is it possible to have unique sessions for the same page in different tabs? Lets say I have in one tab this url https://www.test.com/test.aspx?id=123 and another tab with https://www.test.com/test.aspx?id=124. Each one has data loaded for their respective id. If I do something in the first tab that saves a value in a Session and then do the same with the second tab, if I switch to the first tab and make a PostBack (like calling an event that saves the information), the Session value from the second tab will be saved on the first. How can I avoid that?
This is a big pain - and one that I wish a built in option/setting was available.
However, what often works VERY well?
You can use session to pass value(s) to a page, but ONCE you get on that page and the first page load (Is PostBack = False), then transfer/save the few passed values into ViewState. ViewState is quite much as easy and flexible as Session(), and it is a persisting set of values that is per page, and per tab. And it qiute much is the same if you used a bunch of hidden field controls for this anyway.
So, don't use the session() for persisting of values on a page, but use session() to pass values.
So now, you can have multiple pages open - and you only grabbed/used the session() to get values on first page load - after that, you code using ViewState. Now you want to be careful, since viewstate is browser side based - and you don't want to overload it. (put much data in Viewstate - since whatever you have in ViewState WILL MAKE round trips and lives in the browser - every post back will send this data from client side to server.
ViewState is also how asp.net manages all your controls. So if you have a bunch of text boxes - and do a post-back? you note that these controls values persist automatic for you. This works for you by asp.net using Viewstate. And Even if you have two of the same pages loaded - you note that text boxes etc. still persist for each of the pages.
Session() = for global types of values for that user - applies to all pages.
ViewState() = for per page values.
So, if you use session() to pass values to that page - say a new tab, then on first page load - transfer the few values to ViewState. Those values now are local to the one page, and are not effected by other tabs/pages open - even when pages are on the same page.
Related
I simply need to copy the textbox input data to another page. i have a datagridview from Home.aspx when i select data from it. it will display the row data to the textbox. now i want to copy/pass the data to another page. how can i do that? i tried following codes but it does not work.
This is the 2ndPage Code on load_page
If Not Page.PreviousPage Is Nothing Then
Dim SourceTextBox As TextBox
SourceTextBox = CType(PreviousPage.FindControl("TextBox1"), _
TextBox)
If Not SourceTextBox Is Nothing Then
Label1.Text = SourceTextBox.Text
End If
End If
Ok, a truckload of issues here.
First up:
page.previouspage is ONLY available if you used
Server.Transfer("~/MyCoolWebPage.aspx")
And as general rule you don't a "server side" transfer/jump/hop to a page this way. Trying to keep this post short, but a server.Transfer() means that no real browser side jump to the page occurs - only a server side transfer. That means that the previous URL does not even change! And thus as a general rule, a jump to a page occures from a button click on a page, and that button click can be a client side (JavaScript) click, or a standard button click that executes the Response.Redirect(). However, in both cases, it really is a client side browser request. You as a general rule thus don't want to build or write a web page that "assumes" that a Server.Transfer() was how you landed on that page.
Because of the above? Well me.Page.PreviousPage is ONLY available if the page you are landing on was the RESULT of a 100% server side re-direction to a new page. And that simply not going to be the case, and thus for the vast majority of your web pages, then page.Previouspage will be null, and of ZERO use to you. (it's simply not available).
So, now we back to traditional means and approaches to "transfer" data to the next page.
Remember, that page is state-less. That means EVEN on the same page, all values, and variables are lost between each page load. Even a simple button click means the page will re-load, but that re-load will see all your values lost. Now most controls such as a text box, or even the gridview can and will keep what is called their state for those "round trips" when you click say on a button.
Now, in your case, no doubt you are clicking on a button, and jumping/loading to a new web page. Thus, all previous controls, data and everything you had in existance on that previous page is all gone, and lost.
So, how to pass values give this "state-less' nature of web pages?
Well, a very common way is to use parameters in the URL. However, I find them quite ugly, and users can also mess with those values. However, for really large web sites, we see the parmaters in the URL often used, and that's because the web site does not want to spent the energy, the time and even the memory and resources to keep track of say 1 million users hitting that web site.
But, there is another very common means to "save" values in what we call a round trip. That handy dandy "temp" storage system is called Session(). Now Session() should be treated as a precious and limited resource, but it is quite much how you can (and should) pass values around. The beauty of these values is they "persist" and keep their values between post-backs. And this includes jumping to another page.
So, to pass that data to the next page?
Simply stuff that data row into the session, and then in the target page, you can then get/grab/use/pull any values from that one row of data.
So right before your response.Redirect("to my 2nd page page"), you can do this:
Session("MyTextBox") = me.TextBox1.Text
Now above is fine for one text box value. But, you want to pass the whole row.
So, you can go:
Session("MyListDataRow") = MyRowOfData
Now, you don't explain how or when or where you selected the one row of data. But you can certainly shove the one row of data into session, and then show/display it on the next page.
One more SUPER DUPER WHOPPER:
If you do pull out the selected row into a datarow (as opposed to datatable, or dataset), then keep in mind that .net serializers don't support the datarow (why, I have no idea!!!). So if you using "in-memory" sessions(), then you are ok. But if you ever decide to adopt SQL based session() management, then that code will start to fail. So, either shove in a ListViewDataItem, or a datatable to pass that row of data, and not a datarow.
I would thus just not pass a "datarow" in Session() and avoid the above horrifying revelation that .net left out that data rows don't support serialization! (holy moly!!!!).
So unless you are using a server.transfer() for this, then page.previous is not valid nor available. And if you using a master page, then you have to first dig and get the master page refernce, and then the ContentPlaceHolder if you ARE using a server transfer and you thus do have use of page.PagePrevious.
Edit:
Having said all of the above? Well, if you have a click event on a listview (or datagrid) row, then a server.transfer actually is "one" of those good use cases in which you may VERY well consider a server.transfer(), since the you have full use of the listview/datagrid data in that 2nd page though use of page.PreviousPage. Just be aware that you have to pull down one more level to get at the content if you using master pages.
I am using two tabs in my page like the attached image.
.
Here, after selecting the value in all dropdownlist controls then, i click the generate button. so, the tab is moved from parameter to report. Then again i click the parameter tab. At this time all my dropdown controls shows null value.
but I want all the dropdown values which i selected before.
how can i get the dropdown control values?
It's important to remember that web pages like this are stateless. One request won't remember anything about another request.
So in your situation, you're putting in data, then it sounds like you're clicking a link (or button) that redirects you to another page, then you try and go back to the first one, and it has to fire off yet another request, with no knowledge of the first one's state.
Given that, it seems like you have two primary options (and dozens of others that I won't bother mentioning):
Move the tabs to be on the same page. (My recommendation)
There are lots of controls out there, or you could easily write one yourself, that don't separate tab pages via multiple requests. If you did that, switching tabs wouldn't lose the data.
Add a "save" button, and disable the other tab.
This way, the user actively has to save the data before being able to leave the page via another tab. The biggest issue here comes in the form of usability.
Which one of those you choose is dependent on a number of factors, not the least of which being code maintainability and the size of requests.
I have a page containing a large amount of controls that can trigger postbacks to the server. I know that it is not considered good practice to have a huge amount controls on one page, but the nature of my ASP.NET web application requires it. Seeing that I have a large amount of controls on this page, I make extensive use of UpdatePanels. I am storing ViewState in Session in order to reduce the response size of the page, which works beautifully.
However, with Fiddler I noticed that the 'asyncPostBackControlIDs' after the '__VIEWSTATE' part of the ajax response contains a list of every control of every UpdatePanel that can trigger a postback. This list is huge! It seems that this list doesn't change much per page, and thus it doesn't make sense to download the entire list every time a postback within an UpdatePanel occurs...
Is there any way to store the 'asyncPostBackControlIDs' on server like you can do with ViewState, or otherwise reduce the size of the 'asyncPostBackControlIDs' list?
AFAIK, there is no documented way for storing asyncPostBackControlIDs else where - further, I am very much in doubt if there can be such possibility because most probably those control ids would be required on client side to decide whether to do regular or asynchronous post-back.
You can set ChildrenAsTriggers property of UpdatePanel to false and register controls manually that are actually triggering the post-back - for example, you may have LinkButton/HyperLink that has java-script handler.
Further, perhaps you may able to reduce the list of controls that can cause post-back. For example, you can use anchors(a) instead of linkbuttons/hyperlinks and then set a hidden variable and then simulate a (hidden) button click. On server side, the value of hidden variable would indicate the actual control responsible for post-back. This way, you can have one button that is a post-back control for many other controls.
Finally, you are really a guy who want to have very efficient request/response streams then abandon ASP.NET control model and rather use ASP.NET MVC. Or at less scale, stop using Update Panels for AJAX (they do complete POST of page and almost entire page cycle is executed at server side) and use script services (along with jquery plugins) instead.
Lastly, you need to see the control ids size with the actual response size - for example, 5K long ids within 100K response may not be a large overhead. Reducing those ids would probably give you 5% savings (if possible) but are efforts for the same worth it?
The problem that I am having is as follows:
I currently have a custom class that generates buttons and places them on a placeholder on a master page.
The events for these buttons put specific values into session that differs values for a database query. In essence, the buttons serve as filters for charts.
After creating all the buttons, I realized that session values will stay constant from page to page, so everytime a user enters a different page while another is open, the filters selected on the open page will remain constant for the new page that is opened.
At first, I wanted to use viewstate rather than session, but then realized that a master page and a content page do not share the same viewstate.
At the current time, I am thinking of using a prefix for the sesson key that will identify what page the filters actually exist for. However, I am not wanting to overload session with numerous values if the user wishes to have many pages open at the same time.
Any solutions that would entail a way to share viewstate (or some other way to store values) between app_code, the master, and the content page?
Use HttpContext.Current.Items, it is a key-value pair collection with a lifetime of a single Http Request.
Have you considered Context.Items?
How many filters are we talking here? Store the filter values in the URL. Have you seen some of the URLs that google or an ecommerce site uses? They are quite long. Here is how I do it:
I store the filter values in the query like, www.chart.com?filter1=val1&filter2=val2 etc.
I user JQuery's query plugin to manipulate the query on the client side, and then request the chart from the server again, using the new query.
This way, I'm not junking up session, cookies, or anything like that, and if the user wants to store a bookmark to a particular chart or email it to a friend, they can and the filters are preserved.
I'm starting to think the answer shown in the following question will work:
ViewState object lost in Master Page Load
Exposing the desired variables via a property.
If the data isn't too long, cookies are a typical solution.
Another option is to use Silverlight isolated storage. The Silverlight control itself could be invisible (no UI).
Previously Called: How to deal with dynamically created controls under load in aspx
in response to a question below: the information required to determine which controls to restore is contained in a dedicated viewstate object.
I am dynamically creating controls in the codebehind page - these controls are all hooked up to click handlers so when a postback occurs I must re-create the previous set of controls, then clear the controls down and generate the new set of controls based on the previous click.
This is coded and working correctly under normal circumstances esentially as follows:
in Page_Load
if not postback generate default buttons
else if postback re-generate buttons that were shown on last page
in click_handler
Clear the dynamically generated buttons created in the Page_Load
generate new buttons based on the specific click being handled
however when the server comes under load we start getting problems:
With 5 users per second we start getting the exception:
Multiple controls with the same ID 'add0' were found. FindControl requires that controls have unique IDs.
With 100 users per second we start getting the exception:
The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases.
Once this occurs all subsequent requests get the same error and IIS has to be re-started.
What could be causeing this and how can I avoid it? Do html requests possibly overwrite and interfere with each other when under load? do objects somehow hand around after a page unload in a manner that would allow the next page load to trip over them?
How are you storing information about the controls you need to restore? If you are using ViewState or ControlState, then I don't see how load could affect things. That's how any of the composite controls do things.
I will say that I saw your second error while using the Infragistics UltraWebGrid, and never was able to track it down. From the call stack, it appeared that EnsureChildControls was being called during the Load phase (or maybe LoadViewState).
A private static variable was being used to store a dictionary of names and table cells so that table cells would not get re-created during the page lifecycle.
The key point is that it was marked static - it should have been an instance variable - the end result being that under load when requests started backing up then multpile requests were sharing this static dictionary.
exactly what happened i'm not 100% sure - but under medium loads FindControl would find multiple controls of the same name, under very high loads it seems one request would try to modify a control (probably add to it) while it was in an invalid state from the other request.
End result - if you dont really know what your doing - prefer instance variable sto static variables.
Everything you have written seems to be correct and doable. Most likely this is an issue with your control generation code. Perhaps if you post some of that we can better find a solution.