tags:

views:

2621

answers:

8

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?
+2  A: 

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.

Telos
im not sure how he would use the viewstate in this problem.
John Boker
You can store objects in it. Viewstate["Object_key"] = val;
Telos
This isn't exactly the purpose of ViewState...
Max Schmeling
No, which is why I started by saying I don't understand not using Session state...It is an option, however.
Telos
+1  A: 

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.

Ben Scheirman
+2  A: 

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.

Aheho
+2  A: 

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)

Max Schmeling
+2  A: 

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.

Chad Braun-Duin
+2  A: 

Using session state seems like the most practical way to do this, its exactly what its designed for.

JNappi
A: 

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

Hodge
A: 

Yea, what aheho said was the case a while back (not using session state on web farm). This was since you couldn't get at the session object if the next round trip the user went to a different server.

I was at a company when we were doing this and we had to write a complex session management system to deal with persisting the sessions to the database and retrieving them so that no matter where the request came in (even different states) the user would still have their session information. It was a pain, but it worked. I'm sure glad there's a better way of doing things now! :)

Nathon Dalton