I have a page that I've been using that pulls a lot of data for people to see. The data updates about every minute... So to decrease server load I cache the page for 60 seconds:
'-----Set Cache
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Server)
Response.Cache.SetValidUntilExpires(True)
'---------------
That was working great... but now I added an asp.net Timer and set the interval to 30 seconds for testing.
I have a timestamp on the page and when the timer.tick event happens and updates the updatepanel, the timestamps are changing.
Protected Sub tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmr.Tick
updatePanel.Update()
End Sub
Prior to the timer, the timestamps would stay the same on a browser refresh because the cache. Now it appears they're updating on each tick event (eliminating the purpose of caching).
Even in 2 browsers side-by-side, the timestamps are updating on EVERY update by each browser...
So it appears that the timer loses the cache and defeats the purpose.
Does anyone know how to solve this issue?
The page does not have any controls (buttons, dropdowns, etc) it just displays data in grids (multiple instances of user controls inserted programatically).
What you've added - basically caches the GET request for the page. The POST (when the timer fires) typically isn't cached. I'd suggest that you not cache the actual page, but the results of your 'a lot of data'. Please take a look into HttpRuntime.Cache
Should I use HttpRuntime.Cache?
Related
I have an ASP webpage that has 52 custom control all maintaining ViewState by loading in the PreInit routine
It is a report generator page that depending on which report, up to 5 of the custom controls are visible but not all of them.
For instance,
The Client report does not need the Employee questions.
And the Employee report does not need the Client questions.
But both need the Date Range questions.
(and all this works perfectly)
BUT...
I would like to instead LOAD ONLY the controls that are appropriate for the report that the user is running. (Which sound to me) like I need to store information on WHICH controls to load in the ViewState.
Problem is... viewstate is not available in the PreInit routine, so I cannot use it to determine which controls to load.
My options are then to store the information on WHICH controls to load in:
SessionState.
Database
URL argument.
Something else I haven't thought of.
Each of which carries its own problems for doing what I need.
What (in your opinion) is the best practice for this.
My code (snip)
Private Sub WebForm2_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
ReportOptions.Controls.Add(UserControl1)
ReportOptions.Controls.Add(UserControl2)
ReportOptions.Controls.Add(UserControl3)
Etc...
End Sub
My HTML (snip)
<div id="ReportOptions" class="ReportOptions" runat="server"/>
Viewstate is not an option because you must reconstruct your page exactly as it was (controls and all) in order to read the view state correctly on a post back.
Session sux. (single threaded in asp.net provider)
Database is way to heavy and an overkill.
URL method is stateless and probably your best bet.
I have a simple timer method in vb, that currently does nothing, it just ticks. Once it does however, all my other code on the page stops working.
as an example, I have image buttons on my page that add controls to a static place holder.
btnCreate.Text = "Create"
btnCreate.ID = "btnCreateSpecialNotes"
AddHandler btnCreate.Click, AddressOf btnCreateSpecialNotes_Click
plhCreateSpecialNotes.Controls.Add(btnCreate)
so without the timer.tick method, that (along with other code not included) would fire off as expected and do what I want, but when the timer.tick happens, everything sort of freezes and nothing works.
My timer is set up as follows
<asp:Timer ID="specialNotesTimer" runat="server" Interval="2000" ontick="specialNotesTimer_Tick"></asp: Timer>
and in the code behind...
Protected Sub specialNotesTimer_Tick(Byval sender as object, Byval e as eventArgs) Handles specialNotesTimer.Tick
'Do things to the page
End Sub
DISCLAIMER: I have never used the System.Web.UI.Timer class.
I think there might be some confusion between client side javascript code and server side C# code.
After reading MSDN, it seems that the Timer control would initiate a full postback every 2000 milliseconds (2 seconds because you say so above). This can only be done in javascript and there needs to be a server side event handler that will perform some task on the server (you call it specialNotesTimer_Tick).
Now, if this task takes longer than 2 seconds to execute, I would assume that you will never see any information on the web page because it would constantly be postbacking (posting back?) and refreshing the screen.
Suggestions:
Reconsider your approach for using a timer
Increase the timer interval
Add an UpdatePanel so the processing happens asynchronously, thus avoiding the screen refresh
Hope this helps.
I think the main problem I had here was the flow of my html wasn't ending. I restarted my page from scratch slowly, and though I used virtually the identical code, I just triple checked all my close tags and what not in html, and that seemed to solve the problem itself.
I'm sorry there isn't a more in depth answer, but I still don't understand why my old code here wasn't working, but re-doing my page from square one worked for me.
Is it a "Best Practice" to always use .IsPostBack in the Page_Load sub routine of a web form like in this example coding?
I hope it's ok to ask this question. If not, I will immediately remove the question.
Basically I want to code the way most of you are coding.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
' More coding will go here.
'--------------------------
End If
Please give pros and cons for it's usage.
It's not so much a case of "Best Practice" but more a case of whether you need to use it at all.
It's true, you would normally put IsPostBack in the Page_Load, though you could also put it in the Page_Init - basically in any of the page events that fire before rendering out the HTML.
You're essentially using the command to, in this case, prevent the code in the body from firing when the page posts back to itself; such as a form submission or AutoPostBack on a server control, for example the DropDownList.
There aren't any, at least that I can think of, pro's and con's. Its a case of need or don't.
An example of when you would ideally need it would be only wanting to get data from the database once and bind it to a DropDownList. This data would be available in the viewstate when you postback. so you wouldn't need to visit the database again on postback.
An example of when you wouldn't put code in it is if you were generating server controls (button for example) that have an event handler, such as click, added at the same time. this would need to be re-generated on postback for the event handler to be available.
The benefit is that you can do your expensive operations only once. Binding to gridView...etc.
Mostly stuff you do not want to perform during a refresh.
It always depends on what you want to optimize. If your initialization code takes a long time, it is better to do it only the first time and let your controls be initialize through ViewState. Then you use If Not IsPostBack.
But if you target for mobile devices where bandwidth is more important, you might turn of the ViewState and initialize your data again on postbacks (you could read it from Cache or from SessionState). Always watch your ViewState, I have seen pages with 20 kByte ViewState or more.
Pros:
less overhead for initialization (e.g. access to database)
less memory on server (session or cache)
Contra:
more bandwith for ViewState
I am working on a project which creates controls dynamically for a form in the page_load event, loads in their current values from the database and saves their values (using FindControl) when the user clicks the continue button.
When I added a control statically in the .aspx page and followed their same procedure of loading the value in the page load and saving it on the button press I found that the value would not save correctly. It seems that it wouldn't save because the click event fires after the page_load, so the page_load of the post back reverted the value and the user entered value was not saved.
The strange thing is that by changing the control to be dynamically created just as all the other controls on the page and keeping the loading and saving the same it now works. Even though the page load still creates the control with the old database value.
It seems like a very fundamental asp .net feature here but i'm just unclear as to what is going on. I suspect it is to do with the timing of creation and maybe when the view state kicks in.
Static page controls are created just like dynamic page controls. The difference might be coming in your Page_Load. Whenever you postback all the controls are created afresh which means they are created with their initial values. This happens because after creating the controls asp.net throws away the controls/objects.
So, when the request comes, the first thing that asp.net does it to recreate the controls by looking at their definitions (in the designer files). On each postback they are created and initialized again losing their state in the process.
But after creating the controls Asp.Net loads any viewstate that is sent along with the request which makes people think that the state is always saved at the server.
What might be happening is that either the viewstate is not enabled for your control (in case they are created in designer), in which case you may try using EnableViewState property to true of the control.
Or, when you're doing a Page_Load, you're forcefully re-initializing everything. And in process losing all the control data. If you could post the logic of Page_Load, it might get clarified.
Make sure that:
you are not setting the value again for the static control in Page_Load. The dynamic control are probably getting around it by grabbing the ViewState and form values at a different stage in the lifecycle.
The dynamic controls are added After the static control. Or at least they are added in a different container. Placement in the control's collection can affect the ViewState, although it doesn't look like your scenario / since what you mention seems to be more about the values in the current post.
The save is happening After the Page_Load in response to the corresponding event.
I've run into similar problems in the past (quite a few times actually), but what helped me the most is understanding the ASP.NET Page Lifecycle.
Microsoft has an article on it which describes it pretty well, but this post by Solomon Shaffer really cleared up everything.
I suggest reading them both and coming back with additional questions regarding to a particular state, when to load/save data etc..
Hope this helps.
Marko
Note that you may want to use Page.IsPostBack property to avoid reinitializing values on button clicks and other events.
private void Page_Load()
{
if (!this.IsPostBack)
{
// Assign values to the controls.
}
}
Rather than using the Session object or storing to the database, I am storing temporary variables that I need persisted to custom ViewState variables. For example, ViewState("MyField1") = 1
When the user hits the browser Rrefresh button, Page.IsPostback is back to False and the ViewState is gone.
My question is. If the user can blow away the Viewstate by refreshing, why would anyone use it?
I know that a Refresh reposts the last submitted page, by why is Page.IsPostback reset to False and the ViewState blown away?
Flame me if you want for creating a potential dup question, but I've read other postings here, and it ain't sinking in...
Update to original post:
I now think that it has to do with postbacks that are performed as a result of clicking on Buttons that are within an UpdatePanel. Can someone help shed some light on this?
When a client refreshes their browser, it re-submits the last full page request issued by the client (which may be a GET or a POST). It does not ever resubmit AJAX requests such as those produced by update panel event triggers ("partial page postbacks").
The fact that Page.IsPostback is false when you refresh the page means that your original request is a GET, so here's what's probably happening:
1) During the initial request, the client sends no form data to the server - hence no hidden field containing view state data (Understanding ASP.NET View State is pretty detailed, but a great read if you want to really understand what's going on). While processing this request, ASP.NET may send some view state back to the client, but the original request is just a URL.
2) When the user clicks a button within an UpdatePanel, they trigger a partial postback during which MyField is set to 1. The UpdatePanel changes the client's view state to reflect the new value.
At this point, if the user submits a POST request by normal means, such as clicking a button, the view state will contain the updated information.
If the user clicks 'Refresh' though, they re-submit the original request from step 1, with no form data and therefore no view state.
Where do you set your ViewState? And where do you re-read your ViewState value? Maybe oyu check its content before asp.net calls the LoadViewState() method.
User hitting refresh and using updatepanel will not work together very well. I quess this is why people say that WebForms provides a leaky abstraction on web programming and some are moving to mvc.
If you're not interested in migrating, I'd give you the advice that do not use updatepanel for too long or big operations, where you can assume that user might refresh the page. Use it for small things like dropdown2 items changing when selection on dropdown1 changes.
Wrapping lots of functionality in one updatepanel will cause trouble, if you just depend on viewstate.
Your question is, "Why would anybody use it."
Viewstate comes in handy for data you know is generated by a post back. Hitting refresh is not a post back, but a fresh request.
So lets say you are browsing a datagrid and you need to know certain bits of data about what they have clicked, on the click event you could store that data in the viewstate and process it during other times in the page life cycle, or subsequent post backs.
ViewState's advantage is that it is just embedded into the HTML, so it is all client side. Where as SessionState is server side, and if you store a great amount of data in the session you can cause your web or db server to work harder to handle that data.
Hope this helps.
Don't know why it works but I had a similair problem and solved it by putting this line in the form_load:
me.myProperty = me.myProperty
where
Public Property myProperty() as String
Get
If Not IsNothing(ViewState("data")) Then
Return CType(ViewState("data"), String)
Else
Return String.Empty
End If
End Get
Set(value As String)
ViewState("data") = value
End Set