Share data between aspx pages - asp.net

I need to share data (string, list, array) between two different aspx pages of the same application. What is the best way to do it if I do not want to use cookies and do not want for data to be visible in url.
a) Form post method
b) Session (cookies?)
c) Sql
d) Server.Transfer
Thanks

In-memory Session will be the simplest and quickest (development-wise) to store data between pages without their contents being visible in the query string (URL), like this:
To store a List<string> in Session, do this:
var listOfStrings = new List<string>();
listOfStrings.Add("1");
listOfStrings.Add("2");
listOfStrings.Add("3");
Session["ListOfStrings"] = listOfStrings;
To retrieve the List<string> from Session, do this:
// Check to see if item in Session is actually there or not
if(Session["ListOfStrings"] != null)
{
// Cast the item in Session to a List<T>, because everything in Session is an object
var myListOfStringsRetrieved = Session["ListOfStrings"] as List<string>;
}
Note: I am assuming you use C#, but this can easily be translated to VB.NET.

Some more details might be helpful. What type of information do you want to share? If it is something that needs to be saved, then perhaps it makes most sense to save the data in your database (or local storage, or what ever you are using) from one page and retrieve it in the other. If it's just temporary data, it probably makes more sense to post the data through a form, or use a session variable. The problem with the session variable is that you might time-out your session. A session variable wouldn't be my first choice.

Related

Pass list of ids between forms

I have an ASP.NET c# project.
I have to pass a list of values (id numbers such as "23,4455,21,2,765,...) from one form to another. Since QueryString is not possible because the list could be long, which is the best way to do it?
Thanks in advance.
Thanks for all your answers, you are helping a lot !!!
I decided to do this:
On the first form:
List lRecipients = new List();
.....
Session["Recipients"] = lRecipients;
On the final form:
List lRecipients = (List)Session["Recipients"];
Session.Remove("Recipients");
You could use Session collection.
In the first page, use:
List<int> listOfInts = new List<int>();
...
Session["someKey"] = listOfInts
And in the second page, retrieve it like this:
List<int> listOfInts = Session["someKey"] as List<int>;
If your using asp.net webforms you can put it into a session variable to pass stuff from page to page. You've got to be concise of the potential performance issues of putting lots of stuff into session mind.
Session["ListOfStff"] = "15,25,44.etc";
There are any number of ways to pass this data. Which you choose will depend on your environment.
Session state is useful, but is constrained by the number of concurrent users on the system and the amount of available memory on the server. Consider this when deciding whether or not to use Session state. If you do choose session state for this operation, be sure to remove the data when you're done processing the request.
You could use a hidden input field, with runat="server" applied to it. This will make its data available server-side, and it will only last for the duration of the request. The pros of this technique are that it's accessible to both the server code and the client-side JavaScript. However, it also means that the size of your request is increased, and it may take more work to get the data where you want it (and back out).
Depending on how much data's involved, you could implement a web service to serialize the data to a temporary storage medium (say, a database table), and get back a "request handle." Then, you could pass the request handle on the query string to the next form and it could use the "handle" to fetch the data from your medium.
There are all kinds of different ways to deal with this scenario, but the best choice will depend on your environment, time to develop, and costs.
For Asp.NET MVC you can use ViewData.
ViewData["ID"] = "";

How to forward data from one page to another

I want to take my data tables data to another page. How can I do this? I am programming in ASP.NET.
You can use QueryString to pass data.
If the data is the same on all pages use the Cache. Otherwise retrieve the data again from the database.
Also you can take a look at this article about possible ways of state management in ASP.NET: Nine Options for Managing Persistent User State in Your ASP.NET Application.
You can pass it as a session variable:
Session['yourData'] = dataYouWantToPass;
Then in the next page you retrieve it like so:
var dataYouWantToPass = (YourDataType)Session['yourData'];
In case of string data it would look like this:
//store in session
Session['stringData'] = "Test string data";
//read from session
var stringData= (String)Session['stringData'];

Data Class in ASP.Net

I am a VB.net winforms programmer attempting to build an ASP.Net app. I use data classes(objects) through reflection in most of my vb projects and was trying to adapt it to ASP.net using the VB code behind. I have a webpage that serves as an add/edit page for contact info. I instatiate my class which grabs the contact data from the data base then I have a process that loops through the controls on the form and matches up with a property in the data class. I can display data no problem. When I edit data and click the submit button my code calls a then loops through the controls on the form again and matches the control to the property of the data class to update the property of the class. However, my data class is no longer valid. I know web programming is different then winforms but I can't seem to get over the hump on this one. Is this the wrong way to go about this? Is my data class only available on the server side? Do I just reinstantiate the initial class and then loop through the propeties and change what the user changed and then call the update method (see redundant)? How can I get data class into a session object (I made an attempt in the past but was under tight deadlines and had to abandon it, maybe I need to revisit it?)?
Thanks
If you decide to keep some of your data in Session, you owe it to yourself to look at this post. Your code will be much cleaner and easier to maintain.
Yes, you need to reload the data class from the database as one option, or use an alternative approach. The reason is web is stateless, so all local variables are destroyed then the server side page unload process occurs. This means that in between requests, you need something to store your data.
You can read/write an object via the Session colleciton, as so:
Session["A"] = myobj;
myobj = (ObjType)Session["A"];
And so session stores an object for a specific user. Alternatively, cache stores application level data, so one instance of an object is available to all users (where session is unique to each user). You can make cache unique to a user by appending a user ID to the cache string.
var o = Cache.Get("A");
if (o != null) { .. }
Cache.Add("A", o, ...);
And so these mechanisms help you temporarily retain data.
You need to save your data class somewhere, usually in a session variable, otherwise it goes away as soon as the page gets sent back the user. Or else you need to recreate the data class again upon posting.

Passing an object from one page to another in ASP.NET

On page1.aspx I have a button tied to a buttonOnClick event in my server side.
Clicking the button runs buttonOnClick method which generates an object (local to buttonOnclick method) with data I would like to use in the construction of a new page.
Basically, I want to open a new (different) page (page2.aspx) in a new tab, but as this page loads, I want it to render based on the contents of the object generated during buttonOnClick.
How one might go about this properly? Up until now I have been passing URL arguments to the new popup (page2.aspx) and I have it build the object, but I would rather do this properly and generate it buttonOnclick and then load page2.aspx in a popup based on what is the object built in the buttonOnclick method.
Store the object in your Session on the first page and then retrieve it on your second page.
On first page:
Session["myobject"] = myObject;
On second page:
MyObject object = (MyObject) Session["myobject"];
The easiest thing to do would be to store the object in the user's Session.
Session["myObject"] = myObject;
To get it out, you will need to cast it back to the type of MyObject, since the Session cache is simply a hashtable of objects.
if (Session["myObject"] != null)
{
MyObject myobj = (MyObject)Session["myObject"];
}
You can access it from both pages this way. Generally, if multiple pages are going to be accessing the same object in Session, I usually store the name of the session key in a centralized location so that it only has to be updated once should you ever decide to change it. Usually I add a resource file to my application and put it in the Properties folder, so I can use it this way:
string key = WebApplication1.Properties.MyObjectSessionKey;
Session[key] = myObject;
Use session state or store the object in a database and pass the id to the second page. The object will need to be serializable for this.

Passing Objects via QueryString

I have object A which in turn has a property of type Object B
Class A
property x as Object B
End Class
On my ASP.NET page when I select a gridview item which maps to an object of type A I serialize the object onto the QueryString and pass it to the next page.
However I run into problems if property x actually has some value as it looks like I exceed the QueryString capacity length of 4k (although I didn't think the objects were that large)
I have already considered the following approaches to do this
Session Variables
Approach not used as I have read that this is bad practice.
Using a unique key for the object and retrieving it on the next page.
Approach not used as the objects do not map to a single instance in a table, they arte composed of data from different databases.
So I guess my question is two fold
Is it worth using GKZip to compress the querystring further (is this possible??)
What other methods would people suggest to do this?
If displaying the url of the next page in the browser does not matter, you could use the context.items collection.
context.items.add("keyA", objectA)
server.transfer("nextPage.aspx")
Then on the next page:
public sub page_load(...)
dim objectA as A = ctype(context.items("keyA"), objectA)
dim objectB as B = objectA.B
end sub
One reason to use this is if you want the users to believe that the next page is really a part of the first page. To them, it only appears as if a PostBack has occurred.
Also, you don't really need a unique key using this approach if the only way to use "next page" is if you first came from "first page". The scope for the context items collections is specific to just this particular request.
I agree with the other posters who mentioned that serialized objects on the querystring is a much worse evil than using session state. If you do use session state, just remember to clear the key you use immediately after using it.
I don't understand why you wouldn't use session state but...
Option 1: Viewstate
Option 2: Form parameters instead of querystring
But also be aware that you do not get the same object back when you serialize/deserialize. You get a new object initialized with the values of the original that were serialized out. You're going to end up with two of the object.
EDIT: You can store values in viewstate using the same syntax as Session state
ViewState["key"] = val;
The value has to be serializeable though.
While storing objects in session might be considered bad practice, it's lightyears better than passing them via serialized querystrings.
Back in classic asp, storing objects in session was considered bad practice because you created thread-affinity, and you also limited your ability to scale the site by adding other web servers. This is no longer a problem with asp.net (as long as you use an external stateserver).
There are other reasons to avoid session variables, but in your case I think that's the way to go.
Another option is to combine the 2 pages that need access to this object into one page, using panels to hide and display the needed "sub-pages" and use viewstate to store the object.
I don't think passing it in the query string, or storing it in the session, is a good idea.
You need one of the following:
a) A caching layer. Something like Microsoft Velocity would work, but I doubt you need something on that scale.
b) Put the keys to each object in the databases that you need in the query string and retrieve them the next time around. (E.g. myurl.com/mypage.aspx?db1objectkey=123&db2objectkey=345&db3objectkey=456)
Using session state seems like the most practical way to do this, its exactly what its designed for.
Cache is probably not the answer here either. As Telos mentioned, I'm not sure why you're not considering session.
If you have a page that depends on this data being available, then you just throw a guard clause in the page load...
public void Page_Load()
{
if(!IsPostBack)
{
const string key = "FunkyObject";
if(Session[key] == null)
Response.Redirect("firstStep.aspx");
var obj = (FunkyObject)Session[key];
DoSomething(obj);
}
}
If session is absolutely out of the quesiton, then you'll have to re-materialize this object on the other page. Just send the unique identifier in the querystring so you can pull it back again.
Session isn't always available. For instance when XSS (cross-site-scripting) security settings on IE prevent the storage of third-party cookies. If your site is being called within an IFrame from a site that's not your DNS domain, your cookies are going to be blocked by default. No cookies = no session.
Another example is where you have to pass control to another website that will make the callback to your site as a pure URL, not a post. In this case you have to store your session parameters in a querystring parameter, something that's tough to do given the 4k size constraint and URL encoding, not to mention encryption, etc.
The issue is that most of the built-in serialisation methods are pretty verbose, thus one has to resort to a roll-your-own method, probably using reflection.
Another reason for not using sessions is simply to give a better user experience; sessions get cleared after N minutes and when the server restarts. OK, in this case a viewstate is preferable, but sometimes it's not possible to use a form. OK, one could rely on JavaScript to do a postback, but again, that's not always possible.
These are the problems I'm currently coding around.
Here is what I do:
Page1.aspx - Add a public property of an instance of my object. Add a button (Button1) with the PostBackURL property set to ~/Page2.aspx
Private _RP as ReportParameters
Public ReadOnly Property ReportParams() as ReportParameters
Get
Return _RP
End Get
End Property
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
_RP = New ReportParameters
_RP.Name = "Report 1"
_RP.Param = "42"
End Sub
Now, on the second page, Page2.aspx add the following to the Markup at the top of the page under the first directive:
<%# PreviousPageType VirtualPath="~/Default.aspx" %>
Then for the Page_Load in the code behind for Page2.aspx, add the following
If Not Page.PreviousPage is Nothing Then
Response.write (PreviousPage.ReportParams.Name & " " & PreviousPage.ReportParams.Param)
End If
Faced with a similar situation what I did, is to XML serialize the object and pass it around as query string parameter. The difficulty with this approach was that despite encoding, the receiving form throws exception saying "potentially dangerous request...". The way I got around was to encrypt the serialized object and then encode to pass it around as query string parameter. Which in turn made the query string tamper proof (bonus wandering into the HMAC territory)!
FormA XML serializes an object > encrypts the serialized string > encode > pass as query string to FormB FormB decrypts the query parameter value (as request.querystring decodes also) > deserialize the resulting XML string to object using XmlSerializer.
I can share my VB.NET code upon request to howIdidit-at-applecart-dot-net

Resources