How do I persist the value of a label through a response.redirect? - asp.net

Here's the situation: I have a label's text set, immediately followed by a response.redirect() call as follows (this is just an example, but I believe it describes my situation accurately):
aspx:
<asp:Label runat="server" Text="default text" />
Code-behind (code called on an onclick event):
Label.Text = "foo";
Response.Redirect("Default.aspx");
When the page renders, the label says "default text". What do I need to do differently? My understanding was that such changes would be done automatically behind the scenes, but apparently, not in this case. Thanks.
For a little extra background, the code-behind snippet is called inside a method that's invoked upon an onclick event. There is more to it, but I only included that which is of interest to this issue.

A Response.Redirect call will ask the user's browser to load the page specified in the URL you give it. Because this is a new request for your page the page utilises the text which is contained in your markup (as I assume that the label text is being set inside a button handler or similar).
If you remove the Response.Redirect call your page should work as advertised.

After a redirect you will loose any state information associated to your controls. If you simply want the page to refresh, remove the redirect. After the code has finished executing, the page will refresh and any state will be kept.
Behind the scenes, this works because ASP.NET writes the state information to a hidden input field on the page. When you click a button, the form is posted and ASP.NET deciphers the viewstate. Your code runs, modifying the state, and after that the state is again written to the hidden field and the cycle continues, until you change the page without a POST. This can happen when clicking an hyperlink to another page, or via Response.Redirect(), which instructs the browser to follow the specified url.

ASP and ASP.Net are inherently stateless unless state is explicitly specified. Normally between PostBacks information like the value of a label is contained in the viewstate, but if you change pages that viewstate is lost because it is was being stored in a hidden field on the page.
If you want to maintain the value of the label between calls you need to use one of the state mechanisms (e.g. Session, Preferences) or communication systems (Request (GET, POST)).
Additionally you may be looking for Server.Transfer which will change who is processing the page behind the scenes. Response.Redirect is designed to ditch your current context in most cases.

To persist state, use Server.Transfer instead of Response.Redirect.

So, if I may answer my own question (according to the FAQ, that's encouraged), the short answer is, you don't persist view state through redirects. View state is for postbacks, not redirects.
Bonus: Everything you ever wanted to know about View State in ASP.NET, with pictures!

For what it's worth (and hopefully it's worth something), Chapter 6 of Pro ASP.NET 3.5 in C# 2008, Second Edition is a terrific resource on the subject. The whole book has been great so far.

Related

ASP.NET how to pass a reference to a particular control

I'm generally an ASP.NET MVC guy, so the "standard" ASP.NET stuff is a little difficult for me to wrap my brain around. I've tried looking for the answer, but the keywords I'm using seem to be too generic... I get a lot of close answers, but not what I'm actually looking for.
I have a grid that is populated from a data set. One of the fields is a dropdown with 4 possible statuses. When the user selects a status, an event is fired in the codebehind to make the change in the db immediately.
There is a particular status that I need to confirm, because once it's selected, it's irreversible. Figuring out how to have the back end pop up a confirmation box was annoying, but I think I have that part done now.
The problem is, if the user confirms that the status they selected for the dropdown was intended, I need to disable any further changes to that dropdown, either by disabling the control or by removing the row altogether. With this requirement, I imagine I need to pass a reference to the specific control that fired the event back to the script, so that it can pass it through the postback, where I would need to consume it.
I have no idea how to pass a reference to the control (what can be used as a reference?) and I have no idea how to use that reference in the postback.
Any help would be greatly appreciated.
;p i was waiting for you to find my post on the issue lol.
but to put it simply, you postback to the page, all members are still available to you if you instantiated something in codebehind. if not, then use FindControl to pull them from DOM. here's the passing values stuff.
as long as you don't kill the lifecycle, you're fine: Passing dropdownlist selected value to another page's dropdown list
and here is the linkspam (full docs): How do I keep TCP/IP socket open in IIS?
probably the articles on session-state and page lifecycle will be of most use.
To prompt the user for confirm add this attribute to dropdownlist.
onchange="return confirm('Confirmation Message');"

Can an asp:Button with Visible=False be submitted by a malicious user?

Such a button is not rendered to the browser, so is there any way a malicious user would be able to trigger the action defined by the invisible button? e.g. with a JavaScript call to WebForm_DoPostBackWithOptions? Would ASP.NET accept a POST that appeared to be triggered by this button, even though it wasn't rendered?
Short answer yes.
It is always up to you (the developer) to ensure data received from user input (in this case a post) is valid. Having said that the asp.net framework will do a lot of verification for you, such as "suspicious looking post values".
It is possible to construct a post to a web endpoint, even if the page you display does not have a submit button.
Edit
This would be an example of security through obscurity and is generally not a best practice. Asp.Net "submit" buttons modify a hidden form field called __EVENTTARGET. The asp.net handlers will inspect this field when determining a button click "event". This value can be spoofed if the attacker knew the name of the event target.
Hiding/showing UI elements are good for improving the user experience, but you should always validate (on the server) user input before performing any business actions.
I don't believe it would, if it's not rendered it shouldn't accept the postback. .net uses hidden fields on the page to know which controls were on the page and can verify that during postback, so it knows what triggered the post back. if the control was not there to begin with it shouldn't accept it.
Yes, this is definitely possible. ASP.NET accepts all POST values for controls defined on the page, visible or not. Beware too of i.e. textfields that are set to "read-only". Don't use readonlyControl.Text after the post, and trust that it has the same value as it had the last time you set it.
Take a look at what is posted when you perform a submit with ASP.NET with i.e. Chrome Developer tools, Fiddler, etc, and you should be able to figure out how to add your own value to an "invisible" text field.

Asp.net output cache substitution with postback in user control

We have a site where all pages are output cached, i.e. the caching is on aspx-level with VaryByParam="*". Now there is a requirement to make a gallup control, i.e. a small "How is this site working for you?" and then when the user clicks an answer the results are shown.
The gallup is implemented as a usercontrol that is added to the master page so gallups can be added to any page to which a gallup is created in the cms. The problem is that output cache naturally caches all clicks so when user no 2 votes he sees the results that where calculated after the first vote on that alternative.
Now I'm trying to use cache substition. I added an asp:Substition tag where the user control used to be, load the control dynamically and render it (using this approach http://coderwall.com/p/4ajzqq). The problem is that the postbacks that voting triggers is never fired. Apparently the method that the substition control executes is loaded outside the page life cycle or too late.
Any ideas?
Regards,
Mathias
I solved this by skipping the substitution control and just used the user control as normal, so the gallup/question view was output cached. Then in the click handler for the answer alternatives I added
Response.Cache.SetNoServerCaching();
which exempted the results view from output cache and hence it was updated as it should.
It is also possible to use Response.Cache.SetNoServerCaching() in Global.asax, using VaryByCustom. It merely requires sensing in Global.asax whether the page is a post-back or not. Here is a code example.

What are the main differences of defining a control statically or creating it dynamically on page load?

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.
}
}

Understanding Postbacks in ASP.NET

For example,
If I have a textbox with runat=server on a page, The value will be posted back to the server so I can access the properties in the code-behind.
However, under the following situations, does it still hold true?
A textbox with runat=server but does not appear in the function that is post back to. For example, a button is also on the page, when clicked a post back occurs and within the method that is raised, this textbox was not used.
Within a MasterPage, will a textbox residing on the Masterpage itself be posted back?
Because just thinking, isn't this mechanism bloated in nature?
If all input controls and its value are posted back on every single button click (even when the input control is not needed), doesn't this deteriorate performance?
Having just one Form Tag on the page really restricts us to using this mechanism?
Truly Understanding ViewState is a must read article on the subject of ASP.NET ViewState
There are several options to cut down on the bloat (and yes, there's a lot of it when dealing with lots of controls):
Use AJAX to post only the items required - although be careful to allow clients that don't have JavaScript enabled to still use the page/ site.
The MVC framework allows multiple form tags to be used so you can group sections if needs be.
Set the EnableViewState to false on pages/ controls.
Break up your pages into smaller ones.
Additionally, check out this brilliant graphical representation of the Page Life Cycle in ASP.NET.
Every input on the page is posted back fully unless you use ajax, because of the single form tag. Welcome to asp.net...
As long as the method that you're hitting on the server-side is a non-static member of the page's class, it'll have access to the textbox and all other controls on the page.
And yes, all controls rendered to the browser (whether in the MasterPage, user control, etc.) will be available on post-back.
You may want to look into Understanding ASP.NET View State.
There surely are performance hits with this architecture, but (depending on complexity of the page) it's usually not an issue from the server load perspective, because hardware upgrades are typically cheaper than additional programming hours spend on optimizing application performance.
With that said, (and as others have pointed out) look into using AJAX if you want to avoid whole page-level postbacks to the server.
Yes, it's all posted back, and yes it can cause bloat. I'm sure if you search for ViewState you will find plenty of people ranting about it and how to minimise it :)
Yes your text box will be available in both cases, yes it is bloated. This is where AJAX comes into play. Using AJAX you can send just the data you need.
If you want to send a minimal ammount of data, you could use a Page Method (static method on page decorated so the script manager builds javascript to call it or you could call it using jquery or other methods), or a script enabled web service works nice as well.
You also have viewstate which can get very large. ASP.Net MVC is a new paradigm instead of using WebForms which doesn't have view state, or post backs. It embraces HTTP instead of hidding it giving developers more control.
The textbox data would be posted back as noted. In addition to using Ajax, disabling view state greatly imporoves your page's performance though even then data in properties critical to the functioning of controls (Control state) would still be posted back.
If you didn't have postback for every control on the form, you wouldn't be able to access it in code-behind. I.e. if in your button press you wanted to modify the property of the text control you couldn't do that because ASP.Net would know nothing about the text control.
Since the communication between the server and the client is stateless and every time a page is server the server forgets all about it Postbacks are important if you want to work with the same page again. No matter what programming language you use, this or similar mechanism exists for processing server side code.
If you wish to minimize postback (viewstate size), do this.
Set enableviewstate=false on all controls that you don't want posted back.
Use AJAX and web services wherever possible (and don't use UpdatePanel).
Use HTML control as much as possible instead of ASP.Net controls.
Hmm.. There are some excellent suggestion in other answers and good links too.
You've pretty much hit the nail on the head with vanilla ASP.NET - it's not very good! In both the instances you describe the answer is yes - the textbox will be sent with the form.
The whole postback/ViewState problem is a bit of a pain, one of the first things any competent ASP.NET developer learns to do is avoid them!

Resources