Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

RegisterHiddenField and then Update Hidden Value

Status
Not open for further replies.

Meleagant

Programmer
Aug 31, 2001
166
US
All,

I'm trying to save the ViewState in a Session variable. Kind of like in this article:
One problem that I am having is with using RegisterHiddenField to set my HiddenInput "__ViewStateGuid".

It seems that when using RegisterHiddenField, once the field is there, I can't update the value of the field. Every post back will generate a new Guid and stuff the new viewstate string into the session. When the LoadPageStateFromPersistenceMedium event fires it grabs the value of the HiddenInput __ViewStateGuid and retrieves that session variable. The only problem is that __ViewStateGuid's value on the page was not changed the last time the SavePageStateToPersistenceMedium event fired.

Is there any way I can get __ViewStateGuid's value to update when using RegisterHiddenField? I've already tried writing the hidden field to the page by using Page.Controls.Add().

Here is the code:
Code:
Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Text
Imports System.Web.UI

Namespace ViewStateHelper

    Public Class PageState
        Inherits Page

        Private Const ViewStateHiddenFieldName As String = "__ViewStateGuid"

        Protected Overloads Overrides Sub SavePageStateToPersistenceMedium(ByVal viewState As Object)

            Dim los As LosFormatter = New LosFormatter
            Dim writer As StringWriter = New StringWriter
            los.Serialize(writer, viewState)

            Dim vsGUID As String = Guid.NewGuid.ToString
            Session(vsGUID.ToString) = writer.ToString

            writer.Close()
[COLOR=green]
            'Dim hd As New HtmlInputHidden
            'hd.Attributes("id") = "__ViewStateGuid"
            'hd.Attributes("name") = "__ViewStateGuid"
            'hd.Value = vsGUID
            'Page.Form.Controls.Add(hd) ** Generates Error "The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)."
            'Page.Controls.Add(hd) ** __ViewStateGuid is not in right place and the LoadPageState... function can't find it.

            'vsGUID is not updated after inital page load.  Causes wrong ViewState to be loaded
[/color]            ClientScript.RegisterHiddenField(ViewStateHiddenFieldName, vsGUID)

        End Sub

        Protected Overloads Overrides Function LoadPageStateFromPersistenceMedium() As Object

            If Not Session(Request.Form(ViewStateHiddenFieldName)) Is Nothing Then

                Dim los As LosFormatter = New LosFormatter
                Return los.Deserialize(Session(Request.Form(ViewStateHiddenFieldName)))
            Else
                Throw New Exception("The viewstate session " & Request.Form(ViewStateHiddenFieldName) & " is missing!")
            End If

        End Function

    End Class

End Namespace

* Sine scientia ars nihil est
* Respondeat superior
 
why would you want to save viewstate in session? viewstate was not meant to persist outside of postbacks. If you need specific information in session then create an object to manage that and save only what you need to session. when returning to the page, pull the values from session.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Some of our pages are huge grid views. The ViewState of these pages easily reach over 300,000 characters. I've already gone through and eliminated the ViewState on all of the controls where I don't need it. But the bigger the grid gets, the bigger the ViewState gets.

I was trying to make overall page size smaller. We seem to have a slow internal network. And the time I am saving by not sending the whole viewstate down to the client and then back to the server seems to make this worth it.

* Sine scientia ars nihil est
* Respondeat superior
 
this is a hack. The problem is the amount of data your pulling, not how the page manages the data.

Have you determined that view state is the problem and not
1. a recursive loop in logic
2. inadequate database indexing
3. ineffecient sql statement

if the page keeps growing as records are added then you need to enable paging. Both on the gridview itself and at the database level. Just paging the gridview still requires all data be posted into viewstate so that won't save you anything.

Any decent data access tool should have paging built in). If you're rolling your own DAL then you need to add this functionality.

once paging is enabled viewstate becomes a non-issue. (although you should see better response times if you disable it altogether.)

Jason Meckley
Programmer
Specialty Bakers, Inc.
 

It's not any sort or recursive logic. I'm pretty certain the DB is indexed properly. These DBs are fairly large and I trust that the guy who is in charge of them (an Olde Tyme C guy) is doing things right. There are other old C, Clipper programs that run against these Oracle databases with out a problem. The SQL statement itself is a fairly complicated bit, but I've seem and written much worse. The end result has to show both detail and summary data and I make liberal use of SYS_CONNECT_BY_PATH, ROW_NUMBER() OVER (PARTITION BY ...), CONNECT BY prev = PRIOR curr ....

Jason, I respect your views and you've helped me greatly in the past, but if this is a hack, then why is this function available and why do I find examples of how to use it.

Hack or not, it seems to be speeding up my remote user's page loads. I just need to be able to somehow change the value of my hidden input when the page posts back. The RegisterHiddenField function doesn't seem to be able to overwrite what was there.

A more basic question is what is contained in the ViewState, or more specifically that serialized string that is in the hidden __ViewState input. I have the ViewState of my grid set to False, but the more rows, the bigger that serialized string gets. If I set Trace="True" in the Page directive, I see that all of my rows in the grid have a ViewState Size of 0. But yet that serialized string could be over 300,000 characters long!

Maybe I am going about this the wrong way, but it is still an improvement for my users. On various pages for controls where I must have the viewstate enabled this helps keep the size of the page down where the viewstate is large.



* Sine scientia ars nihil est
* Respondeat superior
 
then why is this function available and why do I find examples of how to use it
Just because it's available doesn't mean you should use it.

Maybe I am going about this the wrong way, but it is still an improvement for my users.
your absolutely right, and you can't compromise end users for "elegant code". However, in my experience there is nothing more permanent than a temporary fix.

I just need to be able to somehow change the value of my hidden input when the page posts back. The RegisterHiddenField function doesn't seem to be able to overwrite what was there.
This may be a timing issue. viewstate is written just before rendering. when are you setting the value? if you haven't already try the pre/post render event. this occurs after the page is initialized, loaded, and events fired. just before sending the response.

A more basic question is what is contained in the ViewState, or more specifically that serialized string that is in the hidden __ViewState input.
viewstate is the serialization of the state of the webpage. this is how webforms provides state to a stateless environment. it why you check for postback. in pure web development these concepts do not exist.

My understand is the webform model was created, in part, to assist VB 6 desktop developers to convert to web development. Thus statefulness in a stateless environment.

if possible, disable viewstate in the web.confg. then view the page and see if viewstate is still large.

The end result has to show both detail and summary data and I make liberal use of SYS_CONNECT_BY_PATH, ROW_NUMBER() OVER (PARTITION BY ...), CONNECT BY prev = PRIOR curr ....
I'm not familiar with Oracle, but we'll assume the indexing and sql are sufficient. Are these commands related to paging? if not i would run some tests against the current query and a series of paging queries reviewing the execution times.

if the difference is negligible (I don't see how it would be though) then you could preform paging in the code. before binding to the grid.

On various pages for controls where I must have the viewstate enabled this helps keep the size of the page down where the viewstate is large.
do you mean you disable to keep page size down, or enable to keep load time down? the former makes sense, the latter doesn't. since your db is indexed properly hitting the db between postbacks wouldn't decrease preformance.

while storing viewstate in session works now, your only delaying the problem until memory becomes an issue on the server. And this could be more difficult to track down. Then you'll need to move the data from Session to somewhere else.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Those Oracle keywords basically let me "compress" rows. Instead of one row per Employee per Department w/ Salary. This lets me have a summary row for each employee, with their Summed(Summary) and then list their departments in a comma delimited string. Not the greatest example, but you get the idea.

It's not the DB hits that I am worried about, instead it is the transmission of the web page over the network from the web server to the client's PC and then the time it takes IE to put all of the pieces together. The main goal here was to decrease the overall size of the page that goes out over the wire. I'm not instituting this on all of my pages, just those that have large viewstates.

I have paging turned on for most of the grids, but my users are well ... dumb. They don't like it. For whatever reason they prefer to look at 5,000 rows all at once. Paging is an option they can chose before they load up their worklists. I even let then chose the page size. I tell them work with 1,000 records at once, instead of 5,000. The page will load much quicker. They refuse to listen.

One thing I don't understand. The ViewState of the grid is turned off. The more records I put in the grid the larger the value of the hidden __ViewState input. If I trace the page, I can see that all of the Rows in the Grid have a ViewState size = 0. So, even is if a control has its enableviewstate="false" does it still put at least some information into the hidden __ViewState input?


* Sine scientia ars nihil est
* Respondeat superior
 
Just a quick note. Simply turning paging on the gridview will NOT help performance. The built in paging function still retrieves ALL rows, but shows only the set amount. In order to get a permormance gain, you will have to impliment custom paging. Here you would use a stored procedure to pull only the rows you are going to show.
 
Yep got that in place. I had to wrap my entire SQL statement inside another SQL statement and then I could use Oracle's ROWNUM to get the proper number of rows.

Passing in the PageNumber and PageSize:

Select *
From ( ... Big honkin Sql Statement ...)
Where RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize


* Sine scientia ars nihil est
* Respondeat superior
 
yes viewstate still collects some information even with it turned off. as for your users. I feel your pain.

if i recall there is a way to configure viewstate on the server instead of the client. but this was a once and done switch, no code involved. I never used it, just remember reading about it somewhere (a few years ago).

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
But getting back to my original question.... Is there anyway I can get my hidden value updated on the page after it has already been registered on the initial load?

I've tries using Page.Controls.Add and Form.Controls.Add, and even hijacking the HTML stream to inject my ViewState hidden input in the correct place.

Alls I needs is to be able to update the value of that hidden input when the SavePageStateToPersistenceMedium is called. And for what ever reason it only seems to work when I write it out using: ClientScript.RegisterHiddenField(ViewStateHiddenFieldName, vsGUID)

* Sine scientia ars nihil est
* Respondeat superior
 
nope I'm at a loss.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top