After a lot of reading about viewstate I have a pretty solid understanding of how it works. One thing I'm not convinced with yet is why can't I just ignore it and move all the data in the form itself.
Can anyone please give me a use case where using viewstate is mandatory and without it there is no reasonable way of implementing the case?
In other words, give me a scenario where using viewstate is clearly beneficial.
Can anyone please give me a use case where using viewstate is mandatory and without it there is no reasonable way of implementing the case
A bit of a drunken rodeo clown wording here, don't you think? NEVER have I seen anyone suggest or hint or use the word "mandatory"
In other words, give me a scenario where using viewstate is clearly beneficial.
Ok, now that question makes great sense.
And sure, I can think of a dozen cases, but lets take a simple one.
I have system in which we are working on a project. Lots of moving parts.
The user will no doubt come from a previous page, and selected/searched from some type of search screen to select the project we are to work on.
so, I pass a class with all the information I need (not going to pass a nasty 10 or 20 variables in the URL, are we?).
So, in my on-load event, we have this - we are coming from the project select page (a previous page), and now landing on the project "edit" or "working" page for this one project (it could be any kind of project - building a boat, or whatever).
Ok, so in the first page load event, I PASS and take the session() based class and move it RIGHT AWAY into ViewState. (and I give a VERY good reason in a bit as to why we do this. Suffice to say, session() is global to one user, but ViewState is PER web page + per user).
So, we now have tucked away the above cPinfo class into view state.
That class is a set of values and variables that I need for the code to operate correctly on this page.
The class is this (actually, the real one is MUCH more complex, but it don't matter for this explain).
So, our class is defined at the PAGE class level, like this:
Dim cPinfo As New clsProjectInfo
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack = False Then
' before we try to load? - lets check if we have info
If Session("Pinfo") Is Nothing Then
' we don't have project info - jump back to project page
Response.Redirect("~/Portal/MyProjects")
Exit Sub
End If
cPinfo = Session("Pinfo") ' transfer from session to viewstate
ViewState("Pinfo") = cPinfo
Else
cPinfo = ViewState("Pinfo")
End if
So, with above, now ANY and All code has 100% free use of the cPinfo class and the values inside. I don't have to do ANY thing more then above and use ViewState, and now all code behind has free use of that class in any code and in any event.
And the class is this:
<Serializable>
Public Class clsProjectInfo
Public ContactID As Integer = 0
Public ContactGeneralID As Integer = 0
Public PortalComp As String = ""
Public ProjectHeaderID As Integer = 0
Public QuoteNum As Integer = 0
Public UploadGroup As Integer = 0
Public txtNotes As String = ""
Public ProofID As Integer = 0
End Class
So, above has 8 values - and those 8 values are needed by BOATLOADS of code on this page. (the real class has more).
So, say I need to display some customer info on my page.
Say like this:
Dim rst As DataTable
strSQL = "select * from Web_ContactsSalesRep where ContactGeneralID = " & cPinfo.ContactGeneralID
rst = Myrst(strSQL, GetConstr(cPinfo.PortalComp))
If rst.Rows.Count > 0 Then
With rst.Rows(0)
strMyProjects += .Item("CompName") & "</font> - "
End With
End If
So, note in above, I used TWO variables (values) from that class.
ContactGeneralID, and PortalComp.
And lets look at some more code.
' get project info
strSQL = "select * from Web_ProjectHeader where ID = " & cPinfo.ProjectHeaderID
rst = Myrst(strSQL, GetConstr(cPinfo.PortalComp))
Again, I needed in code ProjectHeaderID
And this:
'create all project folders
GetProjectFolder(MyPinfo.QuoteNum, MyPinfo.PortalComp)
So, in above, I needed the Quote number, and PortalComp - 2 variables and values.
I want to display project files, so this:
Dim strSQL As String = "select * from WebUpLoad where ProjectHeaderID = " & cPinfo.ProjectHeaderID &
" ORDER BY DateUpLoaded DESC"
Ok, so you get the idea?
I have a set of variables that boatloads of code requires.
Where do YOU suggest I store and persist these values that boatloads of code requires to operate?
I had to park that information SOME place, right? So where do you propose I save and persist that set of variables I need in code?
I MOST certainly don't want to drop into that page 5 or 15 hidden fields, do I?
And if right now, say I add 5 more values/properties to that class? Then ALL my code and ALL my pages? They now have 100% free use of those values in that class. (and I don't have to go add 15 more hidden fields in 15 web page forms, do I???).
So, next issue:
Why did I not use session()?
Well, as noted, Viewstate is per page, and session() is global to the one user.
But, I can't use session() to persist those values, since what happens if the user opens another copy of their browser, goes back to the project selection page, and now selects a different project to work on? (all of that class info for the NEXT page to operate will be wrong on the OTHER open project edit and working page).
Well, better example? You on a site to buy a house. You select the house on one page, and use session() to store all kinds of information about that house (variables and values in you need in code). Now you jump to the next page to buy the house.
if you use session(), then you can wind up with two web pages open, but session() will have all the values based on the LAST house you picked from the previous web page.
If you click on buy house, you can't use that session() value(s) any more. (because the user might have two copies of web browser open).
So, I follow a design pattern in which I use session() to pass the "set" of variables to the next page, but FIRST code execute is to transfer from session() to ViewState. From that point on, ALL CODE on that page will use ViewState.
This way, the fact that session is global to the user don't matter. If they launch another copy of their browser, select a house (or project or whatever), then I use session to pass to the next page, but from that point on, the values I passed are now in ViewState - and ViewState is per web page - not global to he user.
Now the above is only one of many examples.
but, why don't YOU simple answer this question:
You need a set of values and variables to persist for the current page and code to operate. Say 5, or 8 or 15 values. Where are you going to put them?
Surely you don't suggest that in each web page, I drop in 15 fields, do you? (and if I add 3 more things to that class, am I now to modify 20 pages in the whole site to store such values? Not!!!!).
Now, I could I suppose serialize the class into json, and have ONE hidden field on the page, but then again, that means the data is in plan view if the user hits f12 for browser debug tools. However, to be fair on one ajax page, I do in fact serialize the class into json.
At least ViewState is encrypted. Not 100% super banking like secure, but at least good enough for a set of 5 or 15 variables that my code on that page needs handy all the time in code (and not all that easy for someone to try and change the values).
So, let me flip the question around.
Where would you store and save the persist that set of values that a hodge podge of code behind routines that require those values to operate correctly? What is your solution?
My solution is to persist the class (my set of values) into ViewState.
And as noted, I can't use session(), since then if the user has the same page open two times, then that set of class "variables" required in code will now not work, since we have two different web pages open to two different projects. They thus both need their own values to work with, and for the code to operate correctly.
So, what do you propose for the above?
Seems to me, that using ViewState to store some values and persit some variables required in code behind is a rather handy use of ViewState, right? As I stated, one could put all those values in say the URL (URL queryparms - but then that makes you site ugly, and worse, users can see those values, and mess with them. I can't allow users to mess with database PK values, and thus I am even pushing my luck in the area of security by using ViewState.).
the simple matter is that ViewState is a great place to park some values for code behind that has to persist between post-backs. It would be rather laughable to think, and suggest that we ONLY building pages with controls. We ALSO have all that code behind, and how do you propose we maintain a set of values between post-backs then?
While the ViewState is great and automatic for controls dropped into the page (and we tend to thus not care about those controls). However, ViewState is BEYOND handy for code behind to persist some values when required.
So, I can just shove a few variables into ViewState, and I certainly don't have to or want to drop in say some hidden controls into the page to store and persist such values for the time the user spends on that one page.