I am working on a legacy web application written in VB.NET for ASP.NET 1.1. One particular page has a form with a number of fields. In response to a drop-down box changing value, I am clearing a number of fields, resetting a number of drop-down boxes to the first option, and setting them all to "disabled" in the UI. To do this, I'm using jQuery. I add a CSS class to all of these fields, and then my jQuery selector is something like the following: $("*.my-css-class"). Here's some sample code to explain.
var fields = $("*.fields");
if (some_condition) {
fields.val("");
fields.attr("selectedIndex", 0);
fields.attr("disabled", "disabled");
}
The UI updates as expected in response to the above js code, but when I post back the page in response to a button click, the original values still persist on the server-side related to these controls. For instance, txtSomething is one of the fields with a CSS class "fields" (so it will get selected by the above jQuery selector). The user types "1234" in this text box and submits the form. Either the same page is posted back to itself retaining its values, or I return to this page and prepopulate the values on the server-side (for example, the user clicks an Edit button on a summary page), so the control txtSomething is initialized on the client with the value "1234". My jQuery code clears the value as far as the user sees it in the UI, and then the user clicks a submit button. If I interrogate the value with a jQuery selector, the value of this field is an empty string. When the page is posted back and I'm stepping through the code (or doing something with the value of this control), it is still "1234".
A very important point to make is that these values are sent back to the browser after being submitted once. So, picture a form being submitted, or any case where these values are bound or set on the server-side and outputted to the browser pre-populated (as opposed to being output to the browser with default or empty values). If I load the page as default (empty text boxes), enter some text, and then trigger the js function to clear these fields, the value I typed never makes it to the server.
why do you need to disable those fields? Disabling controls can make them not post values to the server ... at least that is what happens when an asp.net control is disabled server side.
Update 1: couldn't take having the doubt if it was only server side, so I looked it up :) http://www.w3.org/TR/html401/interact/forms.html#h-17.12.1 ... "In this example, the INPUT element is disabled. Therefore, it cannot receive user input nor will its value be submitted with the form.", so I was right, even when disabling it client side it won't post the value
Related
TL,DR: Firefox (and only Firefox) fails to display the right select child element as marked with selected="selected" upon clean refresh of a page, even though it is correct in DOM (but only under certain conditions).
(I do not believe this is a duplicate of HTML select, correct option selected in DOM, but wrong item shown in firefox as I am not using ember.js.)
Background
I'm building a "software management/update server" in ASP.NET WebForms. It stores master copies of applications and serves downloads and updates via a simple API. Each application (or "App" as they're referred to in-code) has a DeptID and a GroupID, which are GUIDs, relating to respective Dept and Group tables. Each Group has a DeptID field also.
On one particular page, used for editing a chosen software application's details, NON-postback requests (.e.g., http://localhost/admin/app/edit.aspx?id=guid-here) will result in calls to the database to populate field data on the page.
In brief, the ASP.net runtime Page_Load event does the following:
Ensures that this load is not a Postback
Verifies than an id parameter was provided in the query string
Populates options in the ddlDept DropdownList (renders as HTML select element) from the Dept table
Pulls all fields from the App record from DB as matched by id into a DataSet
Populates options in the ddlGroup DropdownList (another select) from the Group table, matching the DeptID pulled from the App dataset
Populates the data for all form fields from the App dataset
Important to Note: When you click Save, the page is posted back to the server and field data dumped into the database. If the save operation is successful, the browser is instructed to redirect to the current page's URL using Response.Redirect(Request.Url.ToString), resulting in a "clean load" (non-postback load) of the page.
Expected Behavior:
After the page has been successfully saved, hitting F5 or clicking refresh should result in another clean load (non-postback) of the page, and all fields should be populated just like a direct URL hit on the page.
Actual Behavior:
After the page has been successfully saved, hitting F5 or clicking refresh reloads the page as a non-postback (verified in VS debug), but the ddlGroup select element renders the "default" / first item ("Select One") instead of the item marked selected="selected" in the DOM.
I have stepped through every single line of VB code in debug — and when the server sends the page back after this "post-save" and supposedly "clean" load, the ddlGroup value is correct in code all the way out the door. Only in the browser, and only Firefox specifically, is the displayed value set to the wrong item, even though it's right in the DOM. Refreshing again doesn't help at all. When I try to save again, the RequiredField validator for ddlGroup complains that the field isn't valid, even though, again, it's supposedly right in DOM.
This seems to me to be a very bad Firefox bug.
Thoughts?
So, this isn't really what I consider a proper "solution," but rather more of a stable work-around.
Adding autocomplete="off" to the offending select (DropDownList in the aspx markup) magically prevents Firefox from messing up the displayed element within the select, thus always showing the correct one that is marked selected="selected".
I've gone ahead and added it (and will add it) to all of my DropDownLists / selects from now on... thanks Firefox.
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.
I have a web page and a modal dialog page. On clicking the save button in the show modal dialog. closes the window and returns a value. Now when the
control reaches the JavaScript function of the parent window . I wnt to perform some database operation on the basis of this returned ID.
I am using the following approach to utilize this returned value.
Keeping it in the hidden field and populating the returned value in hidden control.
keeping a hidden button in the parent window, performing the click event when control comes back to JavaScript function of the parent page. Thus in the server side button handler get the value from hidden field and perform database operation on the basis of returned value.
Is this approach fine. Or I can get rid of hidden field
That's not terribly bad provided the ID returned is not sensitive information that someone can use to modify a record that doesn't belong to him. One can perfectly manipulate this ID on the client side for any other ID and have your logic update a different record from what you intended.
If all you are doing is calling a server side method passing this ID; why don't you do the whole update from the pop-window itself (at that point you already know the ID)?
If the parent window (page) is meant to be updated; you can just perform a normal refresh of the page (ie. use window.location to redirect the user to the same page so he can see the update or use Response.Redirect to the same page.)
What you're probably looking for is called AJAX. With AJAX you can communicate with your web server from within your JavaScript code directly. No HTML form posts are required then. You might want to look at frameworks like JQuery. These have easy implementations (cross browser wrappers) to send HTTP requests via AJAX.
Note: I just noticed, you are using ASP.NET. Take a look at ASP.Net AJAX Page Methods.
How can we take decision for viewstate and hidden field in ASP.NET.
In my case i am using page cross post back and by using public properties of first page i am accessing them in second aspx page.
After getting public variable in second aspx page i need to access those value in second page but as soon as i do postback in second page, i am not able to find those value.
Hence to solve this issue i have two solution either use viewstate in second page or using hidden field in second page.
I am not able to decide which one should i use?
The approach is quite the same. Only difference should be the size of stored info (viewstate is using [sometimes encrypted] base64 while hidden fields use plain text unless you encode them yourself), and viewstate allows you to make sure the data was not tampered with thanks to the default validation it has in place.
If the data is small and you want to manipulate the value based on some client-side behaviour, hidden field will be useful.
Difference between view state and a hidden field in asp.net
http://royalarun.blogspot.in/2012/03/difference-between-view-state-and.html
Both are used to store the value during the postback in asp.net , but
In View state - not able to change the value by Client side code i.e java script.
Hidden field - possible to change value by Client side code.
In View state - You can store more than one value like Datatable and Dataset
Hidden field - You can store more than one value in hidden field,by serialized it.
View state data is encrypted and Hidden field is not encrypted
I need to develop a page which has 2 dropdownlist.
Options of dropdownlist 2 are based on selection of dropdownlist 1.
I have 2 methods to change the dropdownlist 2. What will you choose?
1:
Postback when users select dropdownlist 1 and change dropdownlist 2.
Pros:
Can use the postback feature, can use the asp.net validator
Cons:
Need to communicate with server (more traffic)
Users will see the page loading in the status bar.
2:
Get all the data (not very much data) in a JSON object when loading the page and change the dropdownlist 2 using javascript.
Pros:
Don't need to communicate with server(less traffic)
Cons:
Can't use the postback feature and validator and more troublesome to write server validation.
Also, I usually write the JSON object to the page as follows:
var locations = <asp:Literal runat="server" id="litLocation" text="[]" />
And then set the "litLocation" in page_load after the data is processed by datacontractjsonserializer.
Do you do it in the same way?
I prefer the second option, no need to reload the whole page just to refresh one dropdown list. I'd also do the client side dev in jQuery, much easier. You can do the client side validation for the change event of the first dropdown in jQuery as well, and keep the form submit validation in ASP.NET.
Have a look at the selectChain plugin for jQuery (demo's etc here).
Why not have your javascript call the server when the select box is clicked on, using a GET method, and fill in the select box, using json as the response, then, when an option is picked then fill in the second select box with another ajax request.
This would be scalable, in that if you want to add more options you just change the server, and everything is centralized.
You will need to validate when the form is submitted anyway, as it is possible to change a value of a form to something illegal using some debugging tools, such as Firebug, so never trust anything from a webpage until you have validated it.
So, no point worrying about the validation until the form is actually submitted.