my problem is i want to pass value of a label and hidden control which are resides in a datalist say in page1.aspx and i want to access these value in page2.aspx. How can i get the values to another page while clicking on submit button. Is there any better option we have without using sessions, server.transfer, request.querystrings etc. Pls. help. I am using master pages. Can we use previouspage? if so how. Suggest me a better solutions. Thanks in advance.
Yes, you can use PreviousPage, by way of a cross-page post.
First, assign the PostBackUrl property of an <asp:Button> control on the first page to point to the second one.
Next, set the PreviousPage directive on the second page:
<%# PreviousPageType VirtualPath="~/first.aspx" %>
When the second page receives a postback, get the data you need from the first page:
Page previous = Page.PreviousPage;
if (previous != null)
{
Label label = (Label)previous.FindControl("myLabel");
if (label != null)
{
string text = label.Text;
}
}
If you use a hidden input element, then it's value will be available via Request.Form, e.g.
HTML in Page1.aspx
<input type="hidden" name="country" value="Norway" />
C# in Page2.aspx
var country = Request.Form["country"]; // "Norway"
You've certainly eliminated a lot of the usual methods of persisting data between pages. Other than queryString parameters, there are also hidden form values (Adam's example) and cookies which are also accessible from the Request object. If the data is relatively small and not particularly sensitive, you could write it to a cookie on the user's machine.
Alternately, you'd need some sort of persistence mechanism to hold the data. You could write the information to a file on the web server. The obvious downside is that you need to have more complex logic to ensure that data from each user is kept separate, you'd essentially need to create your own session management logic.
The other option that comes to mind would be persisting the information to a database. Unless you need to store and manage a whole bunch of complex data, this really isn't a viable options in most cases. It also comes with most of the same pitfalls as the file storage mechanism.
Unless performance is a real issue, just go with Session.
Related
I looking for strategies others have taken for handling ASP.NET web forms with huge numbers of fields. For example, we have a single page that can have around 200 fields and 3 data entry grids in user controls, Now were looking to add even more. It seems to me that at some point the viewstate, or something, is going to break down. So I'm interested to hear how others have handled this level of fields.
MORE INFO BASED ON GOOD FEEDBACK BELOW: I'm thinking maybe changing my main form to more of a dashboard, and when the user wants to enter/edit a data section they get redirected to a new page entirely. When they're done it redirects back. We already have user controls for the 3 grids (totally different types of data). But User Controls I'm finding are nightmares as far as when they render, interactions with the "parent" etc.
I have a form with over 1500 form fields, no issues as of yet. You should be fine unless your server is resource anemic or you have extraordinary loads.
You should however take note of this massive gotcha that took me unawares:
http://support.microsoft.com/kb/2661403
By default, 1000 form controls is the max you can submit to your page. And there is no error thrown, the page will only accept the first 1000 items, and ignore the rest. Pretty awesome discovery in a production environment...
Fortunately you can override that default with this in your web.config:
<appSettings>
<add key="aspnet:MaxHttpCollectionKeys" value="10000" />
</appSettings>
I wouldn't recommend forms with that many controls, but it was at the insistence of the client :)
I looking for strategies others have taken for handling ASP.NET web
forms with huge numbers of fields.
I like to share "a trick" that I use on the rare case of a form with hundreds of fields. On post back I eliminate the fields that actually not change, or they have some default input. On post back I know the fields that I have eliminate and usually for the default action I do not need to do anything. Eg a not select check box, or an input field that have not change, etc....
That way, the actually post is significant smaller. For example on jQuery here is a simple code:
function cOnSubmit()
{
jQuery(".MyInputCss").each(function(index, domElem)
{
var me = jQuery(domElem);
// just an example - if the default have selected of no action, I eliminate it.
if(me.find("input[type='radio']:checked").val() == "-1")
{
// removing the name is not take part on the post back
me.find("input").removeAttr("name");
}
});
return true;
}
and on the form I call this function as:
<form .... onsubmit="return cOnSubmit();">
It seems to me that at some point the viewstate, or something, is
going to break down.
1) If you have a lot of control, you will end up with Operation is not valid due to the current state of the object.
It can easily be fixed by using MaxHttpCollectionKeys like Chris Hardie's suggested.
Note: a label server control is also counted as one control in addition to textbox server control.
2) The another problem I can think of will be large ViewState.
In order to solve this, you can either store ViewState in StateServer or SQL Server.
Update 12/20/2013:
Sorry, I forget to mention how to save ViewState to Session.
Since you already store SessionState is SQL Server, all you need is to inherit the aspx pages from this BasePage.
public class BasePage : Page
{
protected PageStatePersister _persister;
protected override PageStatePersister PageStatePersister
{
get { return _persister ?? (_persister=new SessionPageStatePersister(this));}
}
}
What are the different ways of communication between asp.net page and a popup page? Query strings etc. Which is most secure?
You say "communication between" the pop-up and the main ASP.NET page. First, I assume that the pop-up is an ASP.NET page as well so the communication from the main page to the pop-up is no different from the communication from one page to the next in a series of pages. That is, you can store and then use data in the session (if the data is available when the main page is loaded), via query strings, etc. Unless the data is sensitive, the simplest way by far is to include a variable in the call to the pop-up that is replaced by the appropriate arguments. Here is a sample image link:
<img style='cursor:hand;' alt="Open Note" onclick="javascript:window.open('NoteEdit.aspx?T=3&UID=<%#NoteUID%>', 'Note', 'HEIGHT=400,WIDTH=420');" src="images/Note.gif" />
Note the "NoteUID" replacement argument.
The more interesting question is how to pass information back to the window that popped up the pop up. To do that, start with this javascript:
<script type="text/javascript">
function OpenHRAResults()
{
opener.location.href="<%#DestName%>";
window.close();
}
</script>
This is taken from code where I re-open a specific page but, as you can guess, you can do all sorts of things with the "opener" window (the window that popped-up the pop up).
Hope this helps...
If you are talking about an actual pop-up page, where you are using window.open from javascript. You have the querystring and Javascript as your only real available options for passing information between.
As for "security" of this. The users will be able to see anything via a querystring, JavaScript can move values across, but they would be existing on the other page. But you could pass something like an excrypted value to make things more secure.
We try to avoid query strings where possible in sometimes they are just too convenient. In those cases we always encrypt the querystring. There are several ways to do this - example of one approach:
http://www.codeproject.com/kb/web-security/querystringencryptionnet.aspx
A few methods
Query strings (window.open('/users/123'..)
Javascript (window.opener)
HTTP POST (open a popup via javascript, set the form target to it's name as target and post)
Sessions or other server side methods
In answer to the security consideration I'd say that query strings in combination with server side security is the way to go. Open the popup passing the information via query strings, then validate that the logged in user has permissions to access that user. Some specific requirements would call for encrypting the querystring data.
For delete operations I'd probably use a postback to avoid problems like "my indexing spider deleted all users".
You don't need to sent the real data to the popup window. Just create a GUID on the opener page.
Create a class in asp.net which represent all the data you need to sent between the popup page and the opener page. For example popupdata
Store the serialized class in the Session with the GUID as the name Session[Guid] = class object
Session[Guid] = popupdata;
Open the popup with f.i. ~/popupwindow.aspx?PageID=Guid
Retrieve the session object with calling the Session[Guid] again (Guid is coming from the PageID querystring.
so on the popup page call popupdata data = (popupdata)Session[Guid];
And then do whatever yuo like withthe data.
If data is changed on the popupwindow you can store it in the Session variable again
and send it back to the opener...
Very secure since no data is sent to the client.
Is it possible to save ViewState information, e.g. to session, so that when you navigate away from the page it is persisted somehow? Then when you return to that page you can reload the view state and the choices you've made are preserved.
Background
I have two pages, a report page, where you can pick data, do some filtering and sorting etc. and a chart-page, where the data you picked from the report page can be presented in different ways, with different choices for presentation.
If the user has tested different presentations, simply using the back-button could mean quite a few clicks before the user's back at the report page. I'd like a direct link to the report page.
Using QueryString to save control states is not an option.
I can't customize the ViewState storage for the whole application.
Yes, it's possible to store the Viewstate in something like a database. You just need to implement one of the viewstate providers. See here for an example using the SqlViewStateProvider.
Edit: Just re-read your post, and saw that you said you couldn't customize how the viewstate is stored for the whole application. If that's the case, you might want to look into storing it in a session. Scott Hanselman discusses that here.
Your link could automatically navigate back the required number of pages using JavaScript. Look at window.history, if you can count the number of pages forward you can navigate back that many.
The ViewState is already designed to persist the state of the user controls. If your user has made a selection and that selection is processed server side with a full page postback the new state of the controls will be saved in the ViewState (hidden input __VIEWSTATE).
If your report is using AJAX and partial page postbacks then you won't get the ViewState on the page anyway.
Just to clarify, the SQLViewstateProvider is NOT an application wide implementation. You have to create a class which inherits from the System.Web.UI.Page object and overrides the Save And Load viewstate methods of the Parent Page class. For each page that you want the viewstate to be saved on server side you then have to inherit from your newly created Page Template (Which in turn inherits and overrides the System.WEb.UI.Page class).
So it is applied on a per-page basis, not on an application-wide basis.
HEADS UP: Some controls might contain some client-side javascript code which may reference the viewstate on client-side (duh). If the viewstate is now stored on server-side you will get a null-reference exception (for instance, clicking a commandfield in a gridview). I'm working on a workaround for this problem, but unfortunately I do not have any concrete solution as of yet.
This is a bad idea, just use querystrings. I would be interested to know why they are not an option.
Im adding textboxes (not a fixed number of textboxes) dynamically to a form on ASP.NET page, how do i read back data from these textboxes?
Assuming you're wanting to access the controls on the postback you'd probably re-create the dynamic controls exactly as they were created on the initial load, then use the page's FindControls method to find the controls. It would probably help to create the textboxes with IDs like Textbox1, Textbox2, etc.
Look at Request.Params and extract them from there. You will, of course, have to give them ids to be able to tell them apart.
From all the ASP.NET apps I've worked with, .NET likes to use the following algorithm when generating the Id for server controls:
ctl00$cphBody$[ControlID]
Try using this algorithm when accessing your data from the dynamically generated textboxes.
When you add them you should be giving them names/ids, and you can use those to reference them.
If not, walk your DOM in javascript to find them inside the form you made - they'll be in the same order you inserted them.
Lastly, they're all available as post/get inputs to your page, so you should be able to look at them all as long as you assigned them different names.
-Adam
When creating textboxes dynamically (presumably using JavaScript, but same goes for ASP.NET controls) give them names in a specific pattern. The one you will be able to recognize later.
On server-side, in any event handler occurring after Page_Init you can iterate through Request.Form collection.
Do not be tempted to use Request.Param because it can be used to apply cross-site request forgery on your application (an attacker could lure user into issuing a GET request which your application would interpret the same as it would interpret a POST one, which is usually not a good thing).
If you are adding dynamic ASP.NET controls (in Page_Render for example) you can also reconstruct controls and use their properties.
You can use FindControl and pass the textbox ID to get an instance of the textbox when post back. The Text property contains the data, given that we are at page load stage or later in the cycle.
When adding dynamic controls, override the CreateChildControls method and add the dynamic controls to control hierarchy at this stage of the cycle.
Remember that in ASP.Net, every postback is a new instance of your class. If you created these controls during a previous postback or on the first view then they were garbage collected with the rest of that previous instance. So to use the controls in this new instance, you need to create them again. If you need the state information loaded for those controls (including any value entered by the user), you also need to create before the viewstate is loaded, meaning you do it during the Init event, rather than the load event.
To create dynamic controls, I would usually use a ASP.NET PlaceHolder Control and add the dynamic controls to this container.
I would give each dynamic control an ID.
You can then subsequently use FindControl on the PlaceHolder to access the dynamic controls.
I say "dynamic controls" to mean controls you add at run-time
If I have a simple piece of data to store (an integer or string for example) I might choose to store that in ViewState, or using a HiddenField control.
Why would I choose one over the other?
ViewState
Hard for the user to decode (thought not impossible), which might be desirable
HiddenField
Value can be used in JavaScript
Are there other pros and cons?
Not really, ViewState is actually stored in a hidden field so the only real difference is the encoding.
Unless you need to manipulate the value with JavaScript or you hope to turn off ViewState on this page altogether then I'd use ViewState. Mostly just because there are third party tools (like this one) which understand ViewState and which won't understand your custom hidden field.
From a maintainability point of view, I'd use ViewState. It's less code for you to write, which comes down to fewer points of failure in your software. It also means that any developers coming after you will have an easier time maintaining your solution.
If you're not entirely comfortable with that, write a property accessor on the page that acts as a facade to retrieve the value from the ViewState. Later, if you feel compelled to convert it to a hidden field, the accessor can handle that switch seemlessly for the rest of the code. Just be sure you document your reasons for doing so.
Viewstate is only good on the page you are on or posting back to. With a hidden field you can access the data on the next page you navigate to (as well as other data) by using PreviousPage method of the Page object like so:
string term = ((TextBox)Page.PreviousPage.FindControl("txtSearchTerm")).Text;
The ViewState is stored in the page itself so it increases the page size and it may cause performance issues.
Also we can configure the application to save the viewstate on server rather than on page itself which might protect from some security issues.
Jomit
The hidden field are invisible on page and their values can be viewed in view source but the value of view-state are encoded and are not readable.
The hidden field value are posted on next page. (Note: use server.transfer to get the value of hidden fields).