Viewstate issues after move to 2.0 from 1.1

G

Guest

I have an app that was originally 1.1, now migrated to 2.0 and have run into
some sporadic viewstate errors...usually saying the viewstate is invalid,
eventvalidation failed or mac error.

My web config does specify a machinekey setting:

<machineKey
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F236A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
validation="SHA1"/>

The errors are occuring during some custom code that i wrote that saves form
data when a user's login times out and restores it by reposting it after the
user logs in.

Specifically, in the global.asax file there is a function as below
(truncated to shorten). When the user's session times out from inactivity,
the entire request.form object (all posted data) is saved in the cache with a
key saved as a cookie on the user's machine.

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As
EventArgs)
' Fires upon attempting to authenticate the user
If (Request.IsAuthenticated) Then
........................
ElseIf (Request.Form.Count > 0 AndAlso
(Request.Cookies("widsplusformkey") Is Nothing OrElse
Request.Cookies("widsplusformkey").Value = "") AndAlso Request.Path.ToLower
<> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <> "login.aspx") Then
Dim guidstring As String = Guid.NewGuid.ToString

' Save any posted form data
System.Web.HttpContext.Current.Cache.Add(guidstring,
Request.Form, Nothing, Now.AddMinutes(16), Cache.NoSlidingExpiration,
Caching.CacheItemPriority.Normal, Nothing)
' save cookie with guid string
Response.Cookies("widsplusformkey").Value = guidstring
Response.Cookies("widsplusformkey").Path = "/widsplus"
Response.Cookies("widsplusformkey").Expires =
Now().AddMinutes(15)
End If
End Sub

Next, on the logon page, once the user is authenticated, it redirects
manually to another page called "formredirect.aspx". The code on that page
(below) custom generates a page reconstructing the form data and then posting
it to the original page the user was on. This preserves the form data so the
user can continue from where they left off.

This process worked 100% fine in ASP.NET 1.1. It is only once the
application was migrated to 2.0 that the errors began. And they only happen
part of the time and almost seem related to the amount of form data that
needs to be reposted?

Any ideas how to correct or why the errors only occur part of the time etc.
I will probably try turning off eventvalidation to see if that is the reason
since it is difference i can see in the data that is posted back.


(Code for formredirect.aspx - aspx file is blank and the below generates all
of the html).

Public Sub OutputFormData()
Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0
Transitional//EN""
""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" + Chr(10))
Response.Write("<html lang=""en"">" + Chr(10))
Response.Write(" <head>" + Chr(10))
Response.Write(" <title>See Spot Reload the Form!!!</title>" +
Chr(10))
Response.Write(" </head>" + Chr(10))
Response.Write(" <body bgcolor=""#ffffff"">" + Chr(10))
Response.Write(" <div id=""showprogress"" style=""DISPLAY:
inline; VISIBILITY: visible; WIDTH: 100%; POSITION: absolute"">" + Chr(10))
Response.Write(" <p align=""center""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" size=""4""
color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br>" + Chr(10))
Response.Write(" <img
src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" color=""#dddddd""
size=""1"">This may take a few moments...</font><br><br>" + Chr(10))
Response.Write(" <a href=""mainmenu.aspx""><font
face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
Menu</b></font></a></p></div>" + Chr(10))

If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

Response.Flush()
If Not (rf Is Nothing) Then
Response.Write("<form name=""Form1"" method=""post""
action=""" + FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
""" id=""Form1"">" + Chr(10))
For i As Integer = 0 To rf.Count - 1
Response.Write("<input type=""hidden"" name=""" +
rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" + rf.Item(i) + """>"
+ Chr(10))
Next
Response.Write("</form>" + Chr(10) + "<script
language=javascript>" + Chr(10) + "window.document.forms['Form1'].submit()" +
Chr(10) + "</script>" + Chr(10))
Response.Write(" </body>")
Response.Write("</html>")
' clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
End If
Else
Response.Write(" </body>")
Response.Write("</html>")
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub
 
G

Guest

Some more info.

I turned of "eventvalidation" (enableeventvalidation=false in web.config)
and that appears to prevent the errors although since they are sporadic i
can't be 100% sure for a couple of days.

So then my question becomes what exactly triggers "event validation" to
return an error? What exactly is it checking?

I prefer not to disable security features so i'd prefer to fix my
redirection function so it doesn't trigger the error rather than disable
event validation.

Robert said:
I have an app that was originally 1.1, now migrated to 2.0 and have run into
some sporadic viewstate errors...usually saying the viewstate is invalid,
eventvalidation failed or mac error.

My web config does specify a machinekey setting:

<machineKey
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F236A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
validation="SHA1"/>

The errors are occuring during some custom code that i wrote that saves form
data when a user's login times out and restores it by reposting it after the
user logs in.

Specifically, in the global.asax file there is a function as below
(truncated to shorten). When the user's session times out from inactivity,
the entire request.form object (all posted data) is saved in the cache with a
key saved as a cookie on the user's machine.

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As
EventArgs)
' Fires upon attempting to authenticate the user
If (Request.IsAuthenticated) Then
........................
ElseIf (Request.Form.Count > 0 AndAlso
(Request.Cookies("widsplusformkey") Is Nothing OrElse
Request.Cookies("widsplusformkey").Value = "") AndAlso Request.Path.ToLower
<> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <> "login.aspx") Then
Dim guidstring As String = Guid.NewGuid.ToString

' Save any posted form data
System.Web.HttpContext.Current.Cache.Add(guidstring,
Request.Form, Nothing, Now.AddMinutes(16), Cache.NoSlidingExpiration,
Caching.CacheItemPriority.Normal, Nothing)
' save cookie with guid string
Response.Cookies("widsplusformkey").Value = guidstring
Response.Cookies("widsplusformkey").Path = "/widsplus"
Response.Cookies("widsplusformkey").Expires =
Now().AddMinutes(15)
End If
End Sub

Next, on the logon page, once the user is authenticated, it redirects
manually to another page called "formredirect.aspx". The code on that page
(below) custom generates a page reconstructing the form data and then posting
it to the original page the user was on. This preserves the form data so the
user can continue from where they left off.

This process worked 100% fine in ASP.NET 1.1. It is only once the
application was migrated to 2.0 that the errors began. And they only happen
part of the time and almost seem related to the amount of form data that
needs to be reposted?

Any ideas how to correct or why the errors only occur part of the time etc.
I will probably try turning off eventvalidation to see if that is the reason
since it is difference i can see in the data that is posted back.


(Code for formredirect.aspx - aspx file is blank and the below generates all
of the html).

Public Sub OutputFormData()
Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0
Transitional//EN""
""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" + Chr(10))
Response.Write("<html lang=""en"">" + Chr(10))
Response.Write(" <head>" + Chr(10))
Response.Write(" <title>See Spot Reload the Form!!!</title>" +
Chr(10))
Response.Write(" </head>" + Chr(10))
Response.Write(" <body bgcolor=""#ffffff"">" + Chr(10))
Response.Write(" <div id=""showprogress"" style=""DISPLAY:
inline; VISIBILITY: visible; WIDTH: 100%; POSITION: absolute"">" + Chr(10))
Response.Write(" <p align=""center""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" size=""4""
color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br>" + Chr(10))
Response.Write(" <img
src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" color=""#dddddd""
size=""1"">This may take a few moments...</font><br><br>" + Chr(10))
Response.Write(" <a href=""mainmenu.aspx""><font
face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
Menu</b></font></a></p></div>" + Chr(10))

If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

Response.Flush()
If Not (rf Is Nothing) Then
Response.Write("<form name=""Form1"" method=""post""
action=""" + FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
""" id=""Form1"">" + Chr(10))
For i As Integer = 0 To rf.Count - 1
Response.Write("<input type=""hidden"" name=""" +
rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" + rf.Item(i) + """>"
+ Chr(10))
Next
Response.Write("</form>" + Chr(10) + "<script
language=javascript>" + Chr(10) + "window.document.forms['Form1'].submit()" +
Chr(10) + "</script>" + Chr(10))
Response.Write(" </body>")
Response.Write("</html>")
' clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
End If
Else
Response.Write(" </body>")
Response.Write("</html>")
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub
 
G

Guest

Hi Robert,

I think the problem you got is because your code simulated the steps taken
by a hacker who might want to violate the security of your site. ASP.NET 2.0
attempts to ensure that all postback requests were triggered by code rendered
from the page’s server side controls (during the previous request). In other
words, ASP.NET validates View State to verify that it came from the correct
page, but your code in the method OutputFormData in formredirect.aspx wrote
everything including the ("<!DOCTYPE>†from scratch.

I would suggest that you turn on back again the enableeventvalidation and
re-program the page named "formredirect.aspx" to use the page controls
collection to add content within the form instead of the Response.Write
method to write an html form to the browser.

Let ASP.NET handles its ViewState to ensure the security of your site.

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com


Robert said:
Some more info.

I turned of "eventvalidation" (enableeventvalidation=false in web.config)
and that appears to prevent the errors although since they are sporadic i
can't be 100% sure for a couple of days.

So then my question becomes what exactly triggers "event validation" to
return an error? What exactly is it checking?

I prefer not to disable security features so i'd prefer to fix my
redirection function so it doesn't trigger the error rather than disable
event validation.

Robert said:
I have an app that was originally 1.1, now migrated to 2.0 and have run into
some sporadic viewstate errors...usually saying the viewstate is invalid,
eventvalidation failed or mac error.

My web config does specify a machinekey setting:

<machineKey
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F236A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
validation="SHA1"/>

The errors are occuring during some custom code that i wrote that saves form
data when a user's login times out and restores it by reposting it after the
user logs in.

Specifically, in the global.asax file there is a function as below
(truncated to shorten). When the user's session times out from inactivity,
the entire request.form object (all posted data) is saved in the cache with a
key saved as a cookie on the user's machine.

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As
EventArgs)
' Fires upon attempting to authenticate the user
If (Request.IsAuthenticated) Then
........................
ElseIf (Request.Form.Count > 0 AndAlso
(Request.Cookies("widsplusformkey") Is Nothing OrElse
Request.Cookies("widsplusformkey").Value = "") AndAlso Request.Path.ToLower
<> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <> "login.aspx") Then
Dim guidstring As String = Guid.NewGuid.ToString

' Save any posted form data
System.Web.HttpContext.Current.Cache.Add(guidstring,
Request.Form, Nothing, Now.AddMinutes(16), Cache.NoSlidingExpiration,
Caching.CacheItemPriority.Normal, Nothing)
' save cookie with guid string
Response.Cookies("widsplusformkey").Value = guidstring
Response.Cookies("widsplusformkey").Path = "/widsplus"
Response.Cookies("widsplusformkey").Expires =
Now().AddMinutes(15)
End If
End Sub

Next, on the logon page, once the user is authenticated, it redirects
manually to another page called "formredirect.aspx". The code on that page
(below) custom generates a page reconstructing the form data and then posting
it to the original page the user was on. This preserves the form data so the
user can continue from where they left off.

This process worked 100% fine in ASP.NET 1.1. It is only once the
application was migrated to 2.0 that the errors began. And they only happen
part of the time and almost seem related to the amount of form data that
needs to be reposted?

Any ideas how to correct or why the errors only occur part of the time etc.
I will probably try turning off eventvalidation to see if that is the reason
since it is difference i can see in the data that is posted back.


(Code for formredirect.aspx - aspx file is blank and the below generates all
of the html).

Public Sub OutputFormData()
Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0
Transitional//EN""
""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" + Chr(10))
Response.Write("<html lang=""en"">" + Chr(10))
Response.Write(" <head>" + Chr(10))
Response.Write(" <title>See Spot Reload the Form!!!</title>" +
Chr(10))
Response.Write(" </head>" + Chr(10))
Response.Write(" <body bgcolor=""#ffffff"">" + Chr(10))
Response.Write(" <div id=""showprogress"" style=""DISPLAY:
inline; VISIBILITY: visible; WIDTH: 100%; POSITION: absolute"">" + Chr(10))
Response.Write(" <p align=""center""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" size=""4""
color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br>" + Chr(10))
Response.Write(" <img
src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" color=""#dddddd""
size=""1"">This may take a few moments...</font><br><br>" + Chr(10))
Response.Write(" <a href=""mainmenu.aspx""><font
face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
Menu</b></font></a></p></div>" + Chr(10))

If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

Response.Flush()
If Not (rf Is Nothing) Then
Response.Write("<form name=""Form1"" method=""post""
action=""" + FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
""" id=""Form1"">" + Chr(10))
For i As Integer = 0 To rf.Count - 1
Response.Write("<input type=""hidden"" name=""" +
rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" + rf.Item(i) + """>"
+ Chr(10))
Next
Response.Write("</form>" + Chr(10) + "<script
language=javascript>" + Chr(10) + "window.document.forms['Form1'].submit()" +
Chr(10) + "</script>" + Chr(10))
Response.Write(" </body>")
Response.Write("</html>")
' clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
End If
Else
Response.Write(" </body>")
Response.Write("</html>")
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub
 
G

Guest

Hi Philip,

Your suggestion was an interesting one and so i implemented it (code is
below). However, I still receive the same viewstate error. I tried having
the page not output viewstate itself. I tried having it output viewstate on
its own. It tried suppressing the original viewstate and i tried not
suppressing it.

In all cases I still get the error. Any other ideas/suggestions re the code
below?

What I'm suspecting is that either of the two below is ultimately
responsible for the error:

1) Because the type of the form controls i generate doesn't match the
original type (obviously i can't tell what the original type was...)
2) and/or the url of the page is being used to validate (the url
formredirection.aspx is not the same as the original).

Because this is in intranet site and didn't originally under 1.1 have event
validation I can probably just set this to false in the web config.

But i agree that ideally I would want to leave it on which is why i'm
spending considerable time trying to figure out a way around this.

Thx.
R-

Code for "formredirection.aspx":

<%@ Page Language="vb" EnableViewState="false" EnableEventValidation="false"
ValidateRequest=false AutoEventWireup="false"
Inherits="WIDSPLUS.NET.formredirection2" CodeFile="formredirection2.aspx.vb"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>See Spot Reload the Form!!!</title>
</head>
<body bgcolor="#ffffff">
<form runat="server">
</form>
</body>
</html>

Code behind:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

If Not (rf Is Nothing) Then
' Clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
' Clear cookies
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
' Output progress indicator
Response.Write("<div id=""showprogress""
style=""DISPLAY: inline; VISIBILITY: visible; WIDTH: 100%; POSITION:
absolute"">" + Chr(10))
Response.Write(" <p align=""center""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" size=""4""
color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br>" + Chr(10))
Response.Write(" <img
src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
Response.Write(" <font face=""verdana""
color=""#dddddd"" size=""1"">This may take a few moments...</font><br><br>" +
Chr(10))
Response.Write(" <a href=""mainmenu.aspx""><font
face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
Menu</b></font></a></p></div>" + Chr(10))
Response.Flush()

' Construct form dynamically
Page.Form.ID = "Form1"
Page.Form.Name = "Form1"
Page.Form.Method = "post"

For i As Integer = 0 To rf.Count - 1
If (rf.GetKey(i).Length < 2 OrElse
rf.GetKey(i).Substring(0, 2) <> "__") Then
Dim control As New HtmlInputHidden()

control.Name = rf.GetKey(i)
control.ID = rf.GetKey(i)
control.Value = rf.Item(i)

Page.Form.Controls.Add(control)
End If
Next
ClientScript.RegisterClientScriptBlock(GetType(String),
"postform", "<script
language=""javascript"">window.document.forms['Form1'].action=""" +
FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
""";window.document.forms['Form1'].submit();</script>")
End If
Else
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub

Phillip Williams said:
Hi Robert,

I think the problem you got is because your code simulated the steps taken
by a hacker who might want to violate the security of your site. ASP.NET 2.0
attempts to ensure that all postback requests were triggered by code rendered
from the page’s server side controls (during the previous request). In other
words, ASP.NET validates View State to verify that it came from the correct
page, but your code in the method OutputFormData in formredirect.aspx wrote
everything including the ("<!DOCTYPE>†from scratch.

I would suggest that you turn on back again the enableeventvalidation and
re-program the page named "formredirect.aspx" to use the page controls
collection to add content within the form instead of the Response.Write
method to write an html form to the browser.

Let ASP.NET handles its ViewState to ensure the security of your site.

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com


Robert said:
Some more info.

I turned of "eventvalidation" (enableeventvalidation=false in web.config)
and that appears to prevent the errors although since they are sporadic i
can't be 100% sure for a couple of days.

So then my question becomes what exactly triggers "event validation" to
return an error? What exactly is it checking?

I prefer not to disable security features so i'd prefer to fix my
redirection function so it doesn't trigger the error rather than disable
event validation.

Robert said:
I have an app that was originally 1.1, now migrated to 2.0 and have run into
some sporadic viewstate errors...usually saying the viewstate is invalid,
eventvalidation failed or mac error.

My web config does specify a machinekey setting:

<machineKey
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F236A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
validation="SHA1"/>

The errors are occuring during some custom code that i wrote that saves form
data when a user's login times out and restores it by reposting it after the
user logs in.

Specifically, in the global.asax file there is a function as below
(truncated to shorten). When the user's session times out from inactivity,
the entire request.form object (all posted data) is saved in the cache with a
key saved as a cookie on the user's machine.

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As
EventArgs)
' Fires upon attempting to authenticate the user
If (Request.IsAuthenticated) Then
........................
ElseIf (Request.Form.Count > 0 AndAlso
(Request.Cookies("widsplusformkey") Is Nothing OrElse
Request.Cookies("widsplusformkey").Value = "") AndAlso Request.Path.ToLower
<> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <> "login.aspx") Then
Dim guidstring As String = Guid.NewGuid.ToString

' Save any posted form data
System.Web.HttpContext.Current.Cache.Add(guidstring,
Request.Form, Nothing, Now.AddMinutes(16), Cache.NoSlidingExpiration,
Caching.CacheItemPriority.Normal, Nothing)
' save cookie with guid string
Response.Cookies("widsplusformkey").Value = guidstring
Response.Cookies("widsplusformkey").Path = "/widsplus"
Response.Cookies("widsplusformkey").Expires =
Now().AddMinutes(15)
End If
End Sub

Next, on the logon page, once the user is authenticated, it redirects
manually to another page called "formredirect.aspx". The code on that page
(below) custom generates a page reconstructing the form data and then posting
it to the original page the user was on. This preserves the form data so the
user can continue from where they left off.

This process worked 100% fine in ASP.NET 1.1. It is only once the
application was migrated to 2.0 that the errors began. And they only happen
part of the time and almost seem related to the amount of form data that
needs to be reposted?

Any ideas how to correct or why the errors only occur part of the time etc.
I will probably try turning off eventvalidation to see if that is the reason
since it is difference i can see in the data that is posted back.


(Code for formredirect.aspx - aspx file is blank and the below generates all
of the html).

Public Sub OutputFormData()
Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0
Transitional//EN""
""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" + Chr(10))
Response.Write("<html lang=""en"">" + Chr(10))
Response.Write(" <head>" + Chr(10))
Response.Write(" <title>See Spot Reload the Form!!!</title>" +
Chr(10))
Response.Write(" </head>" + Chr(10))
Response.Write(" <body bgcolor=""#ffffff"">" + Chr(10))
Response.Write(" <div id=""showprogress"" style=""DISPLAY:
inline; VISIBILITY: visible; WIDTH: 100%; POSITION: absolute"">" + Chr(10))
Response.Write(" <p align=""center""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" size=""4""
color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br>" + Chr(10))
Response.Write(" <img
src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" color=""#dddddd""
size=""1"">This may take a few moments...</font><br><br>" + Chr(10))
Response.Write(" <a href=""mainmenu.aspx""><font
face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
Menu</b></font></a></p></div>" + Chr(10))

If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

Response.Flush()
If Not (rf Is Nothing) Then
Response.Write("<form name=""Form1"" method=""post""
action=""" + FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
""" id=""Form1"">" + Chr(10))
For i As Integer = 0 To rf.Count - 1
Response.Write("<input type=""hidden"" name=""" +
rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" + rf.Item(i) + """>"
+ Chr(10))
Next
Response.Write("</form>" + Chr(10) + "<script
language=javascript>" + Chr(10) + "window.document.forms['Form1'].submit()" +
Chr(10) + "</script>" + Chr(10))
Response.Write(" </body>")
Response.Write("</html>")
' clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
End If
Else
Response.Write(" </body>")
Response.Write("</html>")
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub
 
S

Steven Cheng[MSFT]

Thanks for Phillip's inputs,

Hi Robert,

I think Phillip's description on this is reasonable. Based on the document
of the EnableEventValidation setting:

=============
ASP.NET controls create client-side script to raise post-back events on the
server. Because a malicious user could use the postback script to send
arbitrary post events to server controls, ASP.NET 2.0 controls validate the
event data to ensure the event was raised by client-side code rendered by
the control.
=============

the ASP.NET 2.0 by default will check the postback datas so as to ensure
all the form elements(controls) are generated and rendered by the asp.net
page's control structure rather than manually injected by clientside
user(scripts...). So in your scenario, you use Response.Write to manually
generate the page's content (output html form elements....) which is not
under the control of ASP.NET page control structure, so we'll get such
exception when post back....

As Phillip has suggested, if possible, we'd recommend that we redesign the
page so as to avoid such manual page rendering...

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)


--------------------
| Thread-Topic: Viewstate issues after move to 2.0 from 1.1
| thread-index: AcXwWoXmdxcbpXhTQrqsDjsXYR0hNw==
| X-WBNR-Posting-Host: 64.253.156.46
| From: "=?Utf-8?B?UGhpbGxpcCBXaWxsaWFtcw==?="
<[email protected]>
| References: <[email protected]>
<[email protected]>
| Subject: RE: Viewstate issues after move to 2.0 from 1.1
| Date: Wed, 23 Nov 2005 10:20:03 -0800
| Lines: 165
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 8bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet:360518
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Hi Robert,
|
| I think the problem you got is because your code simulated the steps
taken
| by a hacker who might want to violate the security of your site. ASP.NET
2.0
| attempts to ensure that all postback requests were triggered by code
rendered
| from the page’s server side controls (during the previous request). In
other
| words, ASP.NET validates View State to verify that it came from the
correct
| page, but your code in the method OutputFormData in formredirect.aspx
wrote
| everything including the ("<!DOCTYPE>�from scratch.
|
| I would suggest that you turn on back again the enableeventvalidation and
| re-program the page named "formredirect.aspx" to use the page controls
| collection to add content within the form instead of the Response.Write
| method to write an html form to the browser.
|
| Let ASP.NET handles its ViewState to ensure the security of your site.
|
| --
| HTH,
| Phillip Williams
| http://www.societopia.net
| http://www.webswapp.com
|
|
| "Robert" wrote:
|
| > Some more info.
| >
| > I turned of "eventvalidation" (enableeventvalidation=false in
web.config)
| > and that appears to prevent the errors although since they are sporadic
i
| > can't be 100% sure for a couple of days.
| >
| > So then my question becomes what exactly triggers "event validation" to
| > return an error? What exactly is it checking?
| >
| > I prefer not to disable security features so i'd prefer to fix my
| > redirection function so it doesn't trigger the error rather than
disable
| > event validation.
| >
| > "Robert" wrote:
| >
| > > I have an app that was originally 1.1, now migrated to 2.0 and have
run into
| > > some sporadic viewstate errors...usually saying the viewstate is
invalid,
| > > eventvalidation failed or mac error.
| > >
| > > My web config does specify a machinekey setting:
| > >
| > > <machineKey
| > >
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F23
6A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
| > > decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
| > > validation="SHA1"/>
| > >
| > > The errors are occuring during some custom code that i wrote that
saves form
| > > data when a user's login times out and restores it by reposting it
after the
| > > user logs in.
| > >
| > > Specifically, in the global.asax file there is a function as below
| > > (truncated to shorten). When the user's session times out from
inactivity,
| > > the entire request.form object (all posted data) is saved in the
cache with a
| > > key saved as a cookie on the user's machine.
| > >
| > > Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e
As
| > > EventArgs)
| > > ' Fires upon attempting to authenticate the user
| > > If (Request.IsAuthenticated) Then
| > > ........................
| > > ElseIf (Request.Form.Count > 0 AndAlso
| > > (Request.Cookies("widsplusformkey") Is Nothing OrElse
| > > Request.Cookies("widsplusformkey").Value = "") AndAlso
Request.Path.ToLower
| > > <> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <>
"login.aspx") Then
| > > Dim guidstring As String = Guid.NewGuid.ToString
| > >
| > > ' Save any posted form data
| > > System.Web.HttpContext.Current.Cache.Add(guidstring,
| > > Request.Form, Nothing, Now.AddMinutes(16), Cache.NoSlidingExpiration,
| > > Caching.CacheItemPriority.Normal, Nothing)
| > > ' save cookie with guid string
| > > Response.Cookies("widsplusformkey").Value = guidstring
| > > Response.Cookies("widsplusformkey").Path = "/widsplus"
| > > Response.Cookies("widsplusformkey").Expires =
| > > Now().AddMinutes(15)
| > > End If
| > > End Sub
| > >
| > > Next, on the logon page, once the user is authenticated, it redirects
| > > manually to another page called "formredirect.aspx". The code on
that page
| > > (below) custom generates a page reconstructing the form data and then
posting
| > > it to the original page the user was on. This preserves the form
data so the
| > > user can continue from where they left off.
| > >
| > > This process worked 100% fine in ASP.NET 1.1. It is only once the
| > > application was migrated to 2.0 that the errors began. And they only
happen
| > > part of the time and almost seem related to the amount of form data
that
| > > needs to be reposted?
| > >
| > > Any ideas how to correct or why the errors only occur part of the
time etc.
| > > I will probably try turning off eventvalidation to see if that is the
reason
| > > since it is difference i can see in the data that is posted back.
| > >
| > >
| > > (Code for formredirect.aspx - aspx file is blank and the below
generates all
| > > of the html).
| > >
| > > Public Sub OutputFormData()
| > > Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML
1.0
| > > Transitional//EN""
| > > ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" +
Chr(10))
| > > Response.Write("<html lang=""en"">" + Chr(10))
| > > Response.Write(" <head>" + Chr(10))
| > > Response.Write(" <title>See Spot Reload the
Form!!!</title>" +
| > > Chr(10))
| > > Response.Write(" </head>" + Chr(10))
| > > Response.Write(" <body bgcolor=""#ffffff"">" + Chr(10))
| > > Response.Write(" <div id=""showprogress""
style=""DISPLAY:
| > > inline; VISIBILITY: visible; WIDTH: 100%; POSITION: absolute"">" +
Chr(10))
| > > Response.Write(" <p align=""center""><img
| > > src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" +
Chr(10))
| > > Response.Write(" <font face=""verdana"" size=""4""
| > > color=""#ffcc66""><b>Resubmitting Original Request...Please
| > > Wait...</b></font><br><br>" + Chr(10))
| > > Response.Write(" <img
| > > src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
| > > Response.Write(" <font face=""verdana""
color=""#dddddd""
| > > size=""1"">This may take a few moments...</font><br><br>" + Chr(10))
| > > Response.Write(" <a href=""mainmenu.aspx""><font
| > > face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to
Main
| > > Menu</b></font></a></p></div>" + Chr(10))
| > >
| > > If (Not (Request.Cookies("widsplusformkey") Is Nothing)
AndAlso
| > > Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
| > >
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Val
ue) Is Nothing)) Then
| > > Dim rf As Specialized.NameValueCollection =
| > >
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey"
).Value), Specialized.NameValueCollection)
| > >
| > > Response.Flush()
| > > If Not (rf Is Nothing) Then
| > > Response.Write("<form name=""Form1""
method=""post""
| > > action=""" + FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False) +
| > > """ id=""Form1"">" + Chr(10))
| > > For i As Integer = 0 To rf.Count - 1
| > > Response.Write("<input type=""hidden""
name=""" +
| > > rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" + rf.Item(i)
+ """>"
| > > + Chr(10))
| > > Next
| > > Response.Write("</form>" + Chr(10) + "<script
| > > language=javascript>" + Chr(10) +
"window.document.forms['Form1'].submit()" +
| > > Chr(10) + "</script>" + Chr(10))
| > > Response.Write(" </body>")
| > > Response.Write("</html>")
| > > ' clear the saved post data
| > >
| > >
System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey
").Value)
| > > Response.Cookies("widsplusformkey").Value = ""
| > > Response.Cookies("widsplusformkey").Path =
"/widsplus"
| > > End If
| > > Else
| > > Response.Write(" </body>")
| > > Response.Write("</html>")
| > > Response.Cookies("widsplusformkey").Value = ""
| > > Response.Cookies("widsplusformkey").Path = "/widsplus"
| > >
| > >
Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
| > > False))
| > > End If
| > > End Sub
|
 
G

Guest

Hi Steven,

I agree that this is a better, cleaner approach. In my response, i tried
this however and am still receiving the error. So I'm unsure what I am doing
wrong or if there is a way to do this that will work.

Thx.
R-

Steven Cheng said:
Thanks for Phillip's inputs,

Hi Robert,

I think Phillip's description on this is reasonable. Based on the document
of the EnableEventValidation setting:

=============
ASP.NET controls create client-side script to raise post-back events on the
server. Because a malicious user could use the postback script to send
arbitrary post events to server controls, ASP.NET 2.0 controls validate the
event data to ensure the event was raised by client-side code rendered by
the control.
=============

the ASP.NET 2.0 by default will check the postback datas so as to ensure
all the form elements(controls) are generated and rendered by the asp.net
page's control structure rather than manually injected by clientside
user(scripts...). So in your scenario, you use Response.Write to manually
generate the page's content (output html form elements....) which is not
under the control of ASP.NET page control structure, so we'll get such
exception when post back....

As Phillip has suggested, if possible, we'd recommend that we redesign the
page so as to avoid such manual page rendering...

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)


--------------------
| Thread-Topic: Viewstate issues after move to 2.0 from 1.1
| thread-index: AcXwWoXmdxcbpXhTQrqsDjsXYR0hNw==
| X-WBNR-Posting-Host: 64.253.156.46
| From: "=?Utf-8?B?UGhpbGxpcCBXaWxsaWFtcw==?="
<[email protected]>
| References: <[email protected]>
<[email protected]>
| Subject: RE: Viewstate issues after move to 2.0 from 1.1
| Date: Wed, 23 Nov 2005 10:20:03 -0800
| Lines: 165
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 8bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet:360518
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Hi Robert,
|
| I think the problem you got is because your code simulated the steps
taken
| by a hacker who might want to violate the security of your site. ASP.NET
2.0
| attempts to ensure that all postback requests were triggered by code
rendered
| from the page’s server side controls (during the previous request). In
other
| words, ASP.NET validates View State to verify that it came from the
correct
| page, but your code in the method OutputFormData in formredirect.aspx
wrote
| everything including the ("<!DOCTYPE>�from scratch.
|
| I would suggest that you turn on back again the enableeventvalidation and
| re-program the page named "formredirect.aspx" to use the page controls
| collection to add content within the form instead of the Response.Write
| method to write an html form to the browser.
|
| Let ASP.NET handles its ViewState to ensure the security of your site.
|
| --
| HTH,
| Phillip Williams
| http://www.societopia.net
| http://www.webswapp.com
|
|
| "Robert" wrote:
|
| > Some more info.
| >
| > I turned of "eventvalidation" (enableeventvalidation=false in
web.config)
| > and that appears to prevent the errors although since they are sporadic
i
| > can't be 100% sure for a couple of days.
| >
| > So then my question becomes what exactly triggers "event validation" to
| > return an error? What exactly is it checking?
| >
| > I prefer not to disable security features so i'd prefer to fix my
| > redirection function so it doesn't trigger the error rather than
disable
| > event validation.
| >
| > "Robert" wrote:
| >
| > > I have an app that was originally 1.1, now migrated to 2.0 and have
run into
| > > some sporadic viewstate errors...usually saying the viewstate is
invalid,
| > > eventvalidation failed or mac error.
| > >
| > > My web config does specify a machinekey setting:
| > >
| > > <machineKey
| > >
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F23
6A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
| > > decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
| > > validation="SHA1"/>
| > >
| > > The errors are occuring during some custom code that i wrote that
saves form
| > > data when a user's login times out and restores it by reposting it
after the
| > > user logs in.
| > >
| > > Specifically, in the global.asax file there is a function as below
| > > (truncated to shorten). When the user's session times out from
inactivity,
| > > the entire request.form object (all posted data) is saved in the
cache with a
| > > key saved as a cookie on the user's machine.
| > >
| > > Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e
As
| > > EventArgs)
| > > ' Fires upon attempting to authenticate the user
| > > If (Request.IsAuthenticated) Then
| > > ........................
| > > ElseIf (Request.Form.Count > 0 AndAlso
| > > (Request.Cookies("widsplusformkey") Is Nothing OrElse
| > > Request.Cookies("widsplusformkey").Value = "") AndAlso
Request.Path.ToLower
| > > <> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <>
"login.aspx") Then
| > > Dim guidstring As String = Guid.NewGuid.ToString
| > >
| > > ' Save any posted form data
| > > System.Web.HttpContext.Current.Cache.Add(guidstring,
| > > Request.Form, Nothing, Now.AddMinutes(16), Cache.NoSlidingExpiration,
| > > Caching.CacheItemPriority.Normal, Nothing)
| > > ' save cookie with guid string
| > > Response.Cookies("widsplusformkey").Value = guidstring
| > > Response.Cookies("widsplusformkey").Path = "/widsplus"
| > > Response.Cookies("widsplusformkey").Expires =
| > > Now().AddMinutes(15)
| > > End If
| > > End Sub
| > >
| > > Next, on the logon page, once the user is authenticated, it redirects
| > > manually to another page called "formredirect.aspx". The code on
that page
| > > (below) custom generates a page reconstructing the form data and then
posting
| > > it to the original page the user was on. This preserves the form
data so the
| > > user can continue from where they left off.
| > >
| > > This process worked 100% fine in ASP.NET 1.1. It is only once the
| > > application was migrated to 2.0 that the errors began. And they only
happen
| > > part of the time and almost seem related to the amount of form data
that
| > > needs to be reposted?
| > >
| > > Any ideas how to correct or why the errors only occur part of the
time etc.
| > > I will probably try turning off eventvalidation to see if that is the
reason
| > > since it is difference i can see in the data that is posted back.
| > >
| > >
| > > (Code for formredirect.aspx - aspx file is blank and the below
generates all
| > > of the html).
| > >
| > > Public Sub OutputFormData()
| > > Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML
1.0
| > > Transitional//EN""
| > > ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" +
Chr(10))
| > > Response.Write("<html lang=""en"">" + Chr(10))
| > > Response.Write(" <head>" + Chr(10))
| > > Response.Write(" <title>See Spot Reload the
Form!!!</title>" +
| > > Chr(10))
| > > Response.Write(" </head>" + Chr(10))
| > > Response.Write(" <body bgcolor=""#ffffff"">" + Chr(10))
| > > Response.Write(" <div id=""showprogress""
style=""DISPLAY:
| > > inline; VISIBILITY: visible; WIDTH: 100%; POSITION: absolute"">" +
Chr(10))
| > > Response.Write(" <p align=""center""><img
| > > src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" +
Chr(10))
| > > Response.Write(" <font face=""verdana"" size=""4""
| > > color=""#ffcc66""><b>Resubmitting Original Request...Please
| > > Wait...</b></font><br><br>" + Chr(10))
| > > Response.Write(" <img
| > > src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
| > > Response.Write(" <font face=""verdana""
color=""#dddddd""
| > > size=""1"">This may take a few moments...</font><br><br>" + Chr(10))
| > > Response.Write(" <a href=""mainmenu.aspx""><font
| > > face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to
Main
| > > Menu</b></font></a></p></div>" + Chr(10))
| > >
| > > If (Not (Request.Cookies("widsplusformkey") Is Nothing)
AndAlso
| > > Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
| > >
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Val
ue) Is Nothing)) Then
| > > Dim rf As Specialized.NameValueCollection =
| > >
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey"
).Value), Specialized.NameValueCollection)
| > >
| > > Response.Flush()
| > > If Not (rf Is Nothing) Then
| > > Response.Write("<form name=""Form1""
method=""post""
| > > action=""" + FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False) +
| > > """ id=""Form1"">" + Chr(10))
| > > For i As Integer = 0 To rf.Count - 1
| > > Response.Write("<input type=""hidden""
name=""" +
| > > rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" + rf.Item(i)
+ """>"
| > > + Chr(10))
| > > Next
| > > Response.Write("</form>" + Chr(10) + "<script
| > > language=javascript>" + Chr(10) +
"window.document.forms['Form1'].submit()" +
| > > Chr(10) + "</script>" + Chr(10))
| > > Response.Write(" </body>")
| > > Response.Write("</html>")
| > > ' clear the saved post data
| > >
| > >
System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey
").Value)
| > > Response.Cookies("widsplusformkey").Value = ""
| > > Response.Cookies("widsplusformkey").Path =
"/widsplus"
| > > End If
| > > Else
| > > Response.Write(" </body>")
| > > Response.Write("</html>")
| > > Response.Cookies("widsplusformkey").Value = ""
| > > Response.Cookies("widsplusformkey").Path = "/widsplus"
| > >
| > >
Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
| > > False))
| > > End If
| > > End Sub
|
 
G

Guest

Steven,

Below is the most recent revision i tried of the ASPX and codebehind for the
formredirection page.

What I've found is that if instead of having the clientside script i output
to the page change the form action value to the final page and let the page
post back to itself, then no error is returned. However, of course, this
defeats the purpose.

The moment I use the code at the end of the below where the script changes
the form action for postback to the original page (prior to the user having
timed-out), then i end up with the viewstate error.

I am unable to determine any way to get this to work with eventvalidation
turned on. This may well be by design.

I tried finding a way to dynamically turn of eventvalidation under the
theory that i could perhaps have the final destination page disable it's
eventvalidation temporarily but no property exists for this.

All combinations and modifications I've made have been unable to prevent the
error.

So I'm still left with having to just turn off eventvalidation application
wide in order to make this functionality work.

I'm a bit surprised that MS didn't look at adding this type of functionality
into ASP.NET...i.e. ability to save form data when a timeout occurs for login
and then restore it afterwards. This makes an application much more
user-friendly if you have forms that contain a fair number of fields since if
the user gets interrupted and then goes back, the data is preserved on the
server and restored by the code I wrote after the user re-logs in as opposed
to the common and standard behavior that they do get back to the same page
afterwards but with everything completely blank - all their data lost.

If anyone has suggestions on what speciifically I could change in the below
that would make it work, I'd be very grateful. But I'm getting the
impression this is a lost cause (perhaps by design).

Thx.
R-

Current Code Version:

<%@ Page Language="vb" EnableViewState="true" EnableEventValidation="true"
ValidateRequest=false AutoEventWireup="false"
Inherits="WIDSPLUS.NET.formredirection2" CodeFile="formredirection2.aspx.vb"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>See Spot Reload the Form!!!</title>
</head>
<body bgcolor="#ffffff">
<form runat="server">
</form>
</body>
</html>



Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If (Page.IsPostBack) Then
Exit Sub ' Should not ever happen
End If
If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

If Not (rf Is Nothing) Then
' Clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
' Clear cookies
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
' Output progress indicator
Response.Write("<div id=""showprogress""
style=""DISPLAY: inline; VISIBILITY: visible; WIDTH: 100%; POSITION:
absolute"">" + Chr(10))
Response.Write(" <p align=""center""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" size=""4""
color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br>" + Chr(10))
Response.Write(" <img
src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
Response.Write(" <font face=""verdana""
color=""#dddddd"" size=""1"">This may take a few moments...</font><br><br>" +
Chr(10))
Response.Write(" <a href=""mainmenu.aspx""><font
face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
Menu</b></font></a></p></div>" + Chr(10))
Response.Flush()

' Construct form dynamically
Page.Form.ID = "Form1"
Page.Form.Name = "Form1"
Page.Form.Method = "post"

For i As Integer = 0 To rf.Count - 1
If (rf.GetKey(i).Length < 2 OrElse
rf.GetKey(i).Substring(0, 2) <> "__") Then
Dim control As New HiddenField()

control.ID = rf.GetKey(i)
control.Value = rf.Item(i)
Page.Form.Controls.Add(control)
End If
Next
ClientScript.RegisterClientScriptBlock(GetType(String),
"postform", "<script
language=""javascript"">window.document.forms['Form1'].action=""" +
FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
""";window.document.forms['Form1'].submit();</script>")
End If
Else
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub


Protected Overrides Sub Render(ByVal writer As
System.Web.UI.HtmlTextWriter)
Page.ClientScript.RegisterForEventValidation(Page.Form.ID)
For Each control As Control In Page.Controls
Page.ClientScript.RegisterForEventValidation(control.ID)
Next
MyBase.Render(writer)
End Sub


Robert said:
Hi Steven,

I agree that this is a better, cleaner approach. In my response, i tried
this however and am still receiving the error. So I'm unsure what I am doing
wrong or if there is a way to do this that will work.

Thx.
R-

Steven Cheng said:
Thanks for Phillip's inputs,

Hi Robert,

I think Phillip's description on this is reasonable. Based on the document
of the EnableEventValidation setting:

=============
ASP.NET controls create client-side script to raise post-back events on the
server. Because a malicious user could use the postback script to send
arbitrary post events to server controls, ASP.NET 2.0 controls validate the
event data to ensure the event was raised by client-side code rendered by
the control.
=============

the ASP.NET 2.0 by default will check the postback datas so as to ensure
all the form elements(controls) are generated and rendered by the asp.net
page's control structure rather than manually injected by clientside
user(scripts...). So in your scenario, you use Response.Write to manually
generate the page's content (output html form elements....) which is not
under the control of ASP.NET page control structure, so we'll get such
exception when post back....

As Phillip has suggested, if possible, we'd recommend that we redesign the
page so as to avoid such manual page rendering...

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)


--------------------
| Thread-Topic: Viewstate issues after move to 2.0 from 1.1
| thread-index: AcXwWoXmdxcbpXhTQrqsDjsXYR0hNw==
| X-WBNR-Posting-Host: 64.253.156.46
| From: "=?Utf-8?B?UGhpbGxpcCBXaWxsaWFtcw==?="
<[email protected]>
| References: <[email protected]>
<[email protected]>
| Subject: RE: Viewstate issues after move to 2.0 from 1.1
| Date: Wed, 23 Nov 2005 10:20:03 -0800
| Lines: 165
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 8bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet:360518
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Hi Robert,
|
| I think the problem you got is because your code simulated the steps
taken
| by a hacker who might want to violate the security of your site. ASP.NET
2.0
| attempts to ensure that all postback requests were triggered by code
rendered
| from the page’s server side controls (during the previous request). In
other
| words, ASP.NET validates View State to verify that it came from the
correct
| page, but your code in the method OutputFormData in formredirect.aspx
wrote
| everything including the ("<!DOCTYPE>�from scratch.
|
| I would suggest that you turn on back again the enableeventvalidation and
| re-program the page named "formredirect.aspx" to use the page controls
| collection to add content within the form instead of the Response.Write
| method to write an html form to the browser.
|
| Let ASP.NET handles its ViewState to ensure the security of your site.
|
| --
| HTH,
| Phillip Williams
| http://www.societopia.net
| http://www.webswapp.com
|
|
| "Robert" wrote:
|
| > Some more info.
| >
| > I turned of "eventvalidation" (enableeventvalidation=false in
web.config)
| > and that appears to prevent the errors although since they are sporadic
i
| > can't be 100% sure for a couple of days.
| >
| > So then my question becomes what exactly triggers "event validation" to
| > return an error? What exactly is it checking?
| >
| > I prefer not to disable security features so i'd prefer to fix my
| > redirection function so it doesn't trigger the error rather than
disable
| > event validation.
| >
| > "Robert" wrote:
| >
| > > I have an app that was originally 1.1, now migrated to 2.0 and have
run into
| > > some sporadic viewstate errors...usually saying the viewstate is
invalid,
| > > eventvalidation failed or mac error.
| > >
| > > My web config does specify a machinekey setting:
| > >
| > > <machineKey
| > >
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F23
6A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
| > > decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
| > > validation="SHA1"/>
| > >
| > > The errors are occuring during some custom code that i wrote that
saves form
| > > data when a user's login times out and restores it by reposting it
after the
| > > user logs in.
| > >
| > > Specifically, in the global.asax file there is a function as below
| > > (truncated to shorten). When the user's session times out from
inactivity,
| > > the entire request.form object (all posted data) is saved in the
cache with a
| > > key saved as a cookie on the user's machine.
| > >
| > > Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e
As
| > > EventArgs)
| > > ' Fires upon attempting to authenticate the user
| > > If (Request.IsAuthenticated) Then
| > > ........................
| > > ElseIf (Request.Form.Count > 0 AndAlso
| > > (Request.Cookies("widsplusformkey") Is Nothing OrElse
| > > Request.Cookies("widsplusformkey").Value = "") AndAlso
Request.Path.ToLower
| > > <> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <>
"login.aspx") Then
| > > Dim guidstring As String = Guid.NewGuid.ToString
| > >
| > > ' Save any posted form data
| > > System.Web.HttpContext.Current.Cache.Add(guidstring,
| > > Request.Form, Nothing, Now.AddMinutes(16), Cache.NoSlidingExpiration,
| > > Caching.CacheItemPriority.Normal, Nothing)
| > > ' save cookie with guid string
| > > Response.Cookies("widsplusformkey").Value = guidstring
| > > Response.Cookies("widsplusformkey").Path = "/widsplus"
| > > Response.Cookies("widsplusformkey").Expires =
| > > Now().AddMinutes(15)
| > > End If
| > > End Sub
| > >
| > > Next, on the logon page, once the user is authenticated, it redirects
| > > manually to another page called "formredirect.aspx". The code on
that page
| > > (below) custom generates a page reconstructing the form data and then
posting
| > > it to the original page the user was on. This preserves the form
data so the
| > > user can continue from where they left off.
| > >
| > > This process worked 100% fine in ASP.NET 1.1. It is only once the
| > > application was migrated to 2.0 that the errors began. And they only
happen
| > > part of the time and almost seem related to the amount of form data
that
| > > needs to be reposted?
| > >
| > > Any ideas how to correct or why the errors only occur part of the
time etc.
| > > I will probably try turning off eventvalidation to see if that is the
reason
| > > since it is difference i can see in the data that is posted back.
| > >
| > >
| > > (Code for formredirect.aspx - aspx file is blank and the below
generates all
| > > of the html).
| > >
| > > Public Sub OutputFormData()
| > > Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML
1.0
| > > Transitional//EN""
| > > ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" +
Chr(10))
| > > Response.Write("<html lang=""en"">" + Chr(10))
| > > Response.Write(" <head>" + Chr(10))
| > > Response.Write(" <title>See Spot Reload the
Form!!!</title>" +
| > > Chr(10))
| > > Response.Write(" </head>" + Chr(10))
| > > Response.Write(" <body bgcolor=""#ffffff"">" + Chr(10))
| > > Response.Write(" <div id=""showprogress""
style=""DISPLAY:
| > > inline; VISIBILITY: visible; WIDTH: 100%; POSITION: absolute"">" +
Chr(10))
| > > Response.Write(" <p align=""center""><img
| > > src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" +
Chr(10))
| > > Response.Write(" <font face=""verdana"" size=""4""
| > > color=""#ffcc66""><b>Resubmitting Original Request...Please
| > > Wait...</b></font><br><br>" + Chr(10))
| > > Response.Write(" <img
| > > src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
| > > Response.Write(" <font face=""verdana""
color=""#dddddd""
| > > size=""1"">This may take a few moments...</font><br><br>" + Chr(10))
| > > Response.Write(" <a href=""mainmenu.aspx""><font
| > > face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to
Main
| > > Menu</b></font></a></p></div>" + Chr(10))
| > >
| > > If (Not (Request.Cookies("widsplusformkey") Is Nothing)
AndAlso
| > > Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
| > >
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Val
ue) Is Nothing)) Then
| > > Dim rf As Specialized.NameValueCollection =
| > >
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey"
).Value), Specialized.NameValueCollection)
| > >
| > > Response.Flush()
| > > If Not (rf Is Nothing) Then
| > > Response.Write("<form name=""Form1""
method=""post""
| > > action=""" + FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False) +
| > > """ id=""Form1"">" + Chr(10))
| > > For i As Integer = 0 To rf.Count - 1
| > > Response.Write("<input type=""hidden""
name=""" +
| > > rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" + rf.Item(i)
+ """>"
| > > + Chr(10))
| > > Next
| > > Response.Write("</form>" + Chr(10) + "<script
| > > language=javascript>" + Chr(10) +
"window.document.forms['Form1'].submit()" +
| > > Chr(10) + "</script>" + Chr(10))
| > > Response.Write(" </body>")
| > > Response.Write("</html>")
| > > ' clear the saved post data
| > >
| > >
System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey
").Value)
| > > Response.Cookies("widsplusformkey").Value = ""
| > > Response.Cookies("widsplusformkey").Path =
"/widsplus"
| > > End If
| > > Else
| > > Response.Write(" </body>")
| > > Response.Write("</html>")
| > > Response.Cookies("widsplusformkey").Value = ""
| > > Response.Cookies("widsplusformkey").Path = "/widsplus"
| > >
| > >
Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
| > > False))
| > > End If
| > > End Sub
|
 
G

Guest

Hi Robert,

If I understood your code correctly: you persist the entire form in the
cache and want to repopulate its controls after you login. You could
retrieve the HTMLForm object using the Page.FindControls and then reconstruct
it using all of the rich features available in the Page.Controls collection,
as I did in this example: http://www.societopia.net/samples/page_form1.aspx

Basically I put a form on one page then persisted in the cache and retrieved
all of its controls in the redirected to page without any troubles with the
ViewState.

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com


Robert said:
Hi Philip,

Your suggestion was an interesting one and so i implemented it (code is
below). However, I still receive the same viewstate error. I tried having
the page not output viewstate itself. I tried having it output viewstate on
its own. It tried suppressing the original viewstate and i tried not
suppressing it.

In all cases I still get the error. Any other ideas/suggestions re the code
below?

What I'm suspecting is that either of the two below is ultimately
responsible for the error:

1) Because the type of the form controls i generate doesn't match the
original type (obviously i can't tell what the original type was...)
2) and/or the url of the page is being used to validate (the url
formredirection.aspx is not the same as the original).

Because this is in intranet site and didn't originally under 1.1 have event
validation I can probably just set this to false in the web config.

But i agree that ideally I would want to leave it on which is why i'm
spending considerable time trying to figure out a way around this.

Thx.
R-

Code for "formredirection.aspx":

<%@ Page Language="vb" EnableViewState="false" EnableEventValidation="false"
ValidateRequest=false AutoEventWireup="false"
Inherits="WIDSPLUS.NET.formredirection2" CodeFile="formredirection2.aspx.vb"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>See Spot Reload the Form!!!</title>
</head>
<body bgcolor="#ffffff">
<form runat="server">
</form>
</body>
</html>

Code behind:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

If Not (rf Is Nothing) Then
' Clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
' Clear cookies
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
' Output progress indicator
Response.Write("<div id=""showprogress""
style=""DISPLAY: inline; VISIBILITY: visible; WIDTH: 100%; POSITION:
absolute"">" + Chr(10))
Response.Write(" <p align=""center""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" size=""4""
color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br>" + Chr(10))
Response.Write(" <img
src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
Response.Write(" <font face=""verdana""
color=""#dddddd"" size=""1"">This may take a few moments...</font><br><br>" +
Chr(10))
Response.Write(" <a href=""mainmenu.aspx""><font
face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
Menu</b></font></a></p></div>" + Chr(10))
Response.Flush()

' Construct form dynamically
Page.Form.ID = "Form1"
Page.Form.Name = "Form1"
Page.Form.Method = "post"

For i As Integer = 0 To rf.Count - 1
If (rf.GetKey(i).Length < 2 OrElse
rf.GetKey(i).Substring(0, 2) <> "__") Then
Dim control As New HtmlInputHidden()

control.Name = rf.GetKey(i)
control.ID = rf.GetKey(i)
control.Value = rf.Item(i)

Page.Form.Controls.Add(control)
End If
Next
ClientScript.RegisterClientScriptBlock(GetType(String),
"postform", "<script
language=""javascript"">window.document.forms['Form1'].action=""" +
FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
""";window.document.forms['Form1'].submit();</script>")
End If
Else
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub

Phillip Williams said:
Hi Robert,

I think the problem you got is because your code simulated the steps taken
by a hacker who might want to violate the security of your site. ASP.NET 2.0
attempts to ensure that all postback requests were triggered by code rendered
from the page’s server side controls (during the previous request). In other
words, ASP.NET validates View State to verify that it came from the correct
page, but your code in the method OutputFormData in formredirect.aspx wrote
everything including the ("<!DOCTYPE>†from scratch.

I would suggest that you turn on back again the enableeventvalidation and
re-program the page named "formredirect.aspx" to use the page controls
collection to add content within the form instead of the Response.Write
method to write an html form to the browser.

Let ASP.NET handles its ViewState to ensure the security of your site.

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com


Robert said:
Some more info.

I turned of "eventvalidation" (enableeventvalidation=false in web.config)
and that appears to prevent the errors although since they are sporadic i
can't be 100% sure for a couple of days.

So then my question becomes what exactly triggers "event validation" to
return an error? What exactly is it checking?

I prefer not to disable security features so i'd prefer to fix my
redirection function so it doesn't trigger the error rather than disable
event validation.

:

I have an app that was originally 1.1, now migrated to 2.0 and have run into
some sporadic viewstate errors...usually saying the viewstate is invalid,
eventvalidation failed or mac error.

My web config does specify a machinekey setting:

<machineKey
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F236A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
validation="SHA1"/>

The errors are occuring during some custom code that i wrote that saves form
data when a user's login times out and restores it by reposting it after the
user logs in.

Specifically, in the global.asax file there is a function as below
(truncated to shorten). When the user's session times out from inactivity,
the entire request.form object (all posted data) is saved in the cache with a
key saved as a cookie on the user's machine.

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As
EventArgs)
' Fires upon attempting to authenticate the user
If (Request.IsAuthenticated) Then
........................
ElseIf (Request.Form.Count > 0 AndAlso
(Request.Cookies("widsplusformkey") Is Nothing OrElse
Request.Cookies("widsplusformkey").Value = "") AndAlso Request.Path.ToLower
<> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <> "login.aspx") Then
Dim guidstring As String = Guid.NewGuid.ToString

' Save any posted form data
System.Web.HttpContext.Current.Cache.Add(guidstring,
Request.Form, Nothing, Now.AddMinutes(16), Cache.NoSlidingExpiration,
Caching.CacheItemPriority.Normal, Nothing)
' save cookie with guid string
Response.Cookies("widsplusformkey").Value = guidstring
Response.Cookies("widsplusformkey").Path = "/widsplus"
Response.Cookies("widsplusformkey").Expires =
Now().AddMinutes(15)
End If
End Sub

Next, on the logon page, once the user is authenticated, it redirects
manually to another page called "formredirect.aspx". The code on that page
(below) custom generates a page reconstructing the form data and then posting
it to the original page the user was on. This preserves the form data so the
user can continue from where they left off.

This process worked 100% fine in ASP.NET 1.1. It is only once the
application was migrated to 2.0 that the errors began. And they only happen
part of the time and almost seem related to the amount of form data that
needs to be reposted?

Any ideas how to correct or why the errors only occur part of the time etc.
I will probably try turning off eventvalidation to see if that is the reason
since it is difference i can see in the data that is posted back.


(Code for formredirect.aspx - aspx file is blank and the below generates all
of the html).

Public Sub OutputFormData()
Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0
Transitional//EN""
""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" + Chr(10))
Response.Write("<html lang=""en"">" + Chr(10))
Response.Write(" <head>" + Chr(10))
Response.Write(" <title>See Spot Reload the Form!!!</title>" +
Chr(10))
Response.Write(" </head>" + Chr(10))
Response.Write(" <body bgcolor=""#ffffff"">" + Chr(10))
Response.Write(" <div id=""showprogress"" style=""DISPLAY:
inline; VISIBILITY: visible; WIDTH: 100%; POSITION: absolute"">" + Chr(10))
Response.Write(" <p align=""center""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" size=""4""
color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br>" + Chr(10))
Response.Write(" <img
src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
Response.Write(" <font face=""verdana"" color=""#dddddd""
size=""1"">This may take a few moments...</font><br><br>" + Chr(10))
Response.Write(" <a href=""mainmenu.aspx""><font
face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
Menu</b></font></a></p></div>" + Chr(10))

If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

Response.Flush()
If Not (rf Is Nothing) Then
Response.Write("<form name=""Form1"" method=""post""
action=""" + FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
""" id=""Form1"">" + Chr(10))
For i As Integer = 0 To rf.Count - 1
Response.Write("<input type=""hidden"" name=""" +
rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" + rf.Item(i) + """>"
+ Chr(10))
Next
Response.Write("</form>" + Chr(10) + "<script
language=javascript>" + Chr(10) + "window.document.forms['Form1'].submit()" +
Chr(10) + "</script>" + Chr(10))
Response.Write(" </body>")
Response.Write("</html>")
' clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
End If
Else
Response.Write(" </body>")
Response.Write("</html>")
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub
 
S

Steven Cheng[MSFT]

Hey Robert,

Thanks for your quick response.
From your further description and the code snippet you provided, seems
you're still using the Response.Write .... means to output page content(
this is usually what the old ASP or other scripting based dynamic document
use...). Is it possible that we change to utilize the ASP.NET server
control model , using Response.Write is really not a good idea. I'd rather
recommend you just clear up the ASPX's content and using the following code
block inline (as classic ASP do)

<%@page .....%>

<%

//all code here

%>


Also, as for your problem on
===================
The moment I use the code at the end of the below where the script changes
the form action for postback to the original page (prior to the user having
timed-out), then i end up with the viewstate error.
===================

if you're using the new ASP.NET control model, you 'll find that ASP.NET
2.0 provide "CrossPage Posting" functionality which help us to easily post
from one aspx page to another (we don't need to manually change the html
form's action attribute...), what we need to do is changing the Button
Control's PostBackUrl property , like:

protected void RadioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton rb = (RadioButton)sender;

if (rb == RadioButton1)
{
btnPostBack.PostBackUrl = "~/AccessTestPage.aspx";
}
else
{
btnPostBack.PostBackUrl = "~/FtpWebPage.aspx";
}
}


#Cross-Page Posting in ASP.NET Web Pages
http://msdn2.microsoft.com/en-us/library/ms178139.aspx


In addition, as for storing form's post data for later use, I think this is
done by default for ASP.NET page (if viewstate enabled), most of each
server control's properties will be persisted in ViewState for sequential
postback use... However, when there occurs timeout, of course, this is an
exceptional scenario, we need to write our own code to handel it (e.g store
them in cache or any other storage and reset them to asp.net page's
controls properties later....). Again this require that we utilize the
ASP.NET page control model ....

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)






--------------------
| Thread-Topic: Viewstate issues after move to 2.0 from 1.1
| thread-index: AcXwwFvzbT+awft0ROCI4qVIXc4SAA==
| X-WBNR-Posting-Host: 67.180.214.235
| From: =?Utf-8?B?Um9iZXJ0?= <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| Subject: RE: Viewstate issues after move to 2.0 from 1.1
| Date: Wed, 23 Nov 2005 22:29:01 -0800
| Lines: 437
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 8bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet:360636
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Steven,
|
| Below is the most recent revision i tried of the ASPX and codebehind for
the
| formredirection page.
|
| What I've found is that if instead of having the clientside script i
output
| to the page change the form action value to the final page and let the
page
| post back to itself, then no error is returned. However, of course, this
| defeats the purpose.
|
| The moment I use the code at the end of the below where the script
changes
| the form action for postback to the original page (prior to the user
having
| timed-out), then i end up with the viewstate error.
|
| I am unable to determine any way to get this to work with eventvalidation
| turned on. This may well be by design.
|
| I tried finding a way to dynamically turn of eventvalidation under the
| theory that i could perhaps have the final destination page disable it's
| eventvalidation temporarily but no property exists for this.
|
| All combinations and modifications I've made have been unable to prevent
the
| error.
|
| So I'm still left with having to just turn off eventvalidation
application
| wide in order to make this functionality work.
|
| I'm a bit surprised that MS didn't look at adding this type of
functionality
| into ASP.NET...i.e. ability to save form data when a timeout occurs for
login
| and then restore it afterwards. This makes an application much more
| user-friendly if you have forms that contain a fair number of fields
since if
| the user gets interrupted and then goes back, the data is preserved on
the
| server and restored by the code I wrote after the user re-logs in as
opposed
| to the common and standard behavior that they do get back to the same
page
| afterwards but with everything completely blank - all their data lost.
|
| If anyone has suggestions on what speciifically I could change in the
below
| that would make it work, I'd be very grateful. But I'm getting the
| impression this is a lost cause (perhaps by design).
|
| Thx.
| R-
|
| Current Code Version:
|
| <%@ Page Language="vb" EnableViewState="true"
EnableEventValidation="true"
| ValidateRequest=false AutoEventWireup="false"
| Inherits="WIDSPLUS.NET.formredirection2"
CodeFile="formredirection2.aspx.vb"
| %>
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
| <head>
| <title>See Spot Reload the Form!!!</title>
| </head>
| <body bgcolor="#ffffff">
| <form runat="server">
| </form>
| </body>
| </html>
|
|
|
| Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
| System.EventArgs) Handles MyBase.Load
| 'Put user code to initialize the page here
| If (Page.IsPostBack) Then
| Exit Sub ' Should not ever happen
| End If
| If (Not (Request.Cookies("widsplusformkey") Is Nothing)
AndAlso
| Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
|
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Val
ue) Is Nothing)) Then
| Dim rf As Specialized.NameValueCollection =
|
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey"
).Value), Specialized.NameValueCollection)
|
| If Not (rf Is Nothing) Then
| ' Clear the saved post data
|
|
System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey
").Value)
| ' Clear cookies
| Response.Cookies("widsplusformkey").Value = ""
| Response.Cookies("widsplusformkey").Path = "/widsplus"
| ' Output progress indicator
| Response.Write("<div id=""showprogress""
| style=""DISPLAY: inline; VISIBILITY: visible; WIDTH: 100%; POSITION:
| absolute"">" + Chr(10))
| Response.Write(" <p align=""center""><img
| src=""globalimages/transp.gif"" width=""5"" height=""50""><br>" + Chr(10))
| Response.Write(" <font face=""verdana"" size=""4""
| color=""#ffcc66""><b>Resubmitting Original Request...Please
| Wait...</b></font><br><br>" + Chr(10))
| Response.Write(" <img
| src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
| Response.Write(" <font face=""verdana""
| color=""#dddddd"" size=""1"">This may take a few
moments...</font><br><br>" +
| Chr(10))
| Response.Write(" <a href=""mainmenu.aspx""><font
| face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel & Return to Main
| Menu</b></font></a></p></div>" + Chr(10))
| Response.Flush()
|
| ' Construct form dynamically
| Page.Form.ID = "Form1"
| Page.Form.Name = "Form1"
| Page.Form.Method = "post"
|
| For i As Integer = 0 To rf.Count - 1
| If (rf.GetKey(i).Length < 2 OrElse
| rf.GetKey(i).Substring(0, 2) <> "__") Then
| Dim control As New HiddenField()
|
| control.ID = rf.GetKey(i)
| control.Value = rf.Item(i)
| Page.Form.Controls.Add(control)
| End If
| Next
|
ClientScript.RegisterClientScriptBlock(GetType(String),
| "postform", "<script
| language=""javascript"">window.document.forms['Form1'].action=""" +
| FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) +
| """;window.document.forms['Form1'].submit();</script>")
| End If
| Else
| Response.Cookies("widsplusformkey").Value = ""
| Response.Cookies("widsplusformkey").Path = "/widsplus"
|
| Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
| False))
| End If
| End Sub
|
|
| Protected Overrides Sub Render(ByVal writer As
| System.Web.UI.HtmlTextWriter)
| Page.ClientScript.RegisterForEventValidation(Page.Form.ID)
| For Each control As Control In Page.Controls
| Page.ClientScript.RegisterForEventValidation(control.ID)
| Next
| MyBase.Render(writer)
| End Sub
|
|
| "Robert" wrote:
|
| > Hi Steven,
| >
| > I agree that this is a better, cleaner approach. In my response, i
tried
| > this however and am still receiving the error. So I'm unsure what I am
doing
| > wrong or if there is a way to do this that will work.
| >
| > Thx.
| > R-
| >
| > "Steven Cheng[MSFT]" wrote:
| >
| > > Thanks for Phillip's inputs,
| > >
| > > Hi Robert,
| > >
| > > I think Phillip's description on this is reasonable. Based on the
document
| > > of the EnableEventValidation setting:
| > >
| > > =============
| > > ASP.NET controls create client-side script to raise post-back events
on the
| > > server. Because a malicious user could use the postback script to
send
| > > arbitrary post events to server controls, ASP.NET 2.0 controls
validate the
| > > event data to ensure the event was raised by client-side code
rendered by
| > > the control.
| > > =============
| > >
| > > the ASP.NET 2.0 by default will check the postback datas so as to
ensure
| > > all the form elements(controls) are generated and rendered by the
asp.net
| > > page's control structure rather than manually injected by clientside
| > > user(scripts...). So in your scenario, you use Response.Write to
manually
| > > generate the page's content (output html form elements....) which is
not
| > > under the control of ASP.NET page control structure, so we'll get
such
| > > exception when post back....
| > >
| > > As Phillip has suggested, if possible, we'd recommend that we
redesign the
| > > page so as to avoid such manual page rendering...
| > >
| > > Thanks,
| > >
| > > Steven Cheng
| > > Microsoft Online Support
| > >
| > > Get Secure! www.microsoft.com/security
| > > (This posting is provided "AS IS", with no warranties, and confers no
| > > rights.)
| > >
| > >
| > > --------------------
| > > | Thread-Topic: Viewstate issues after move to 2.0 from 1.1
| > > | thread-index: AcXwWoXmdxcbpXhTQrqsDjsXYR0hNw==
| > > | X-WBNR-Posting-Host: 64.253.156.46
| > > | From: "=?Utf-8?B?UGhpbGxpcCBXaWxsaWFtcw==?="
| > > <[email protected]>
| > > | References: <[email protected]>
| > > <[email protected]>
| > > | Subject: RE: Viewstate issues after move to 2.0 from 1.1
| > > | Date: Wed, 23 Nov 2005 10:20:03 -0800
| > > | Lines: 165
| > > | Message-ID: <[email protected]>
| > > | MIME-Version: 1.0
| > > | Content-Type: text/plain;
| > > | charset="Utf-8"
| > > | Content-Transfer-Encoding: 8bit
| > > | X-Newsreader: Microsoft CDO for Windows 2000
| > > | Content-Class: urn:content-classes:message
| > > | Importance: normal
| > > | Priority: normal
| > > | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| > > | Newsgroups: microsoft.public.dotnet.framework.aspnet
| > > | NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| > > | Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA03.phx.gbl
| > > | Xref: TK2MSFTNGXA02.phx.gbl
| > > microsoft.public.dotnet.framework.aspnet:360518
| > > | X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
| > > |
| > > | Hi Robert,
| > > |
| > > | I think the problem you got is because your code simulated the
steps
| > > taken
| > > | by a hacker who might want to violate the security of your site.
ASP.NET
| > > 2.0
| > > | attempts to ensure that all postback requests were triggered by
code
| > > rendered
| > > | from the page’s server side controls (during the previous
request). In
| > > other
| > > | words, ASP.NET validates View State to verify that it came from the
| > > correct
| > > | page, but your code in the method OutputFormData in
formredirect.aspx
| > > wrote
| > > | everything including the ("<!DOCTYPE>â�from scratch.
| > > |
| > > | I would suggest that you turn on back again the
enableeventvalidation and
| > > | re-program the page named "formredirect.aspx" to use the page
controls
| > > | collection to add content within the form instead of the
Response.Write
| > > | method to write an html form to the browser.
| > > |
| > > | Let ASP.NET handles its ViewState to ensure the security of your
site.
| > > |
| > > | --
| > > | HTH,
| > > | Phillip Williams
| > > | http://www.societopia.net
| > > | http://www.webswapp.com
| > > |
| > > |
| > > | "Robert" wrote:
| > > |
| > > | > Some more info.
| > > | >
| > > | > I turned of "eventvalidation" (enableeventvalidation=false in
| > > web.config)
| > > | > and that appears to prevent the errors although since they are
sporadic
| > > i
| > > | > can't be 100% sure for a couple of days.
| > > | >
| > > | > So then my question becomes what exactly triggers "event
validation" to
| > > | > return an error? What exactly is it checking?
| > > | >
| > > | > I prefer not to disable security features so i'd prefer to fix my
| > > | > redirection function so it doesn't trigger the error rather than
| > > disable
| > > | > event validation.
| > > | >
| > > | > "Robert" wrote:
| > > | >
| > > | > > I have an app that was originally 1.1, now migrated to 2.0 and
have
| > > run into
| > > | > > some sporadic viewstate errors...usually saying the viewstate
is
| > > invalid,
| > > | > > eventvalidation failed or mac error.
| > > | > >
| > > | > > My web config does specify a machinekey setting:
| > > | > >
| > > | > > <machineKey
| > > | > >
| > >
validationKey="447C05E8B3A71401CC4CAE5513A7F1A3494A3618EE819316AAD1D58433F23
| > > 6A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB8367A1649438867A02EB"
| > > | > >
decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA230077AFB86CB"
| > > | > > validation="SHA1"/>
| > > | > >
| > > | > > The errors are occuring during some custom code that i wrote
that
| > > saves form
| > > | > > data when a user's login times out and restores it by reposting
it
| > > after the
| > > | > > user logs in.
| > > | > >
| > > | > > Specifically, in the global.asax file there is a function as
below
| > > | > > (truncated to shorten). When the user's session times out from
| > > inactivity,
| > > | > > the entire request.form object (all posted data) is saved in
the
| > > cache with a
| > > | > > key saved as a cookie on the user's machine.
| > > | > >
| > > | > > Sub Application_AuthenticateRequest(ByVal sender As Object,
ByVal e
| > > As
| > > | > > EventArgs)
| > > | > > ' Fires upon attempting to authenticate the user
| > > | > > If (Request.IsAuthenticated) Then
| > > | > > ........................
| > > | > > ElseIf (Request.Form.Count > 0 AndAlso
| > > | > > (Request.Cookies("widsplusformkey") Is Nothing OrElse
| > > | > > Request.Cookies("widsplusformkey").Value = "") AndAlso
| > > Request.Path.ToLower
| > > | > > <> "/widsplus/login.aspx" AndAlso Request.Path.ToLower <>
| > > "login.aspx") Then
| > > | > > Dim guidstring As String = Guid.NewGuid.ToString
| > > | > >
| > > | > > ' Save any posted form data
| > > | > >
System.Web.HttpContext.Current.Cache.Add(guidstring,
| > > | > > Request.Form, Nothing, Now.AddMinutes(16),
Cache.NoSlidingExpiration,
| > > | > > Caching.CacheItemPriority.Normal, Nothing)
| > > | > > ' save cookie with guid string
| > > | > > Response.Cookies("widsplusformkey").Value =
guidstring
| > > | > > Response.Cookies("widsplusformkey").Path =
"/widsplus"
| > > | > > Response.Cookies("widsplusformkey").Expires =
| > > | > > Now().AddMinutes(15)
| > > | > > End If
| > > | > > End Sub
| > > | > >
| > > | > > Next, on the logon page, once the user is authenticated, it
redirects
| > > | > > manually to another page called "formredirect.aspx". The code
on
| > > that page
| > > | > > (below) custom generates a page reconstructing the form data
and then
| > > posting
| > > | > > it to the original page the user was on. This preserves the
form
| > > data so the
| > > | > > user can continue from where they left off.
| > > | > >
| > > | > > This process worked 100% fine in ASP.NET 1.1. It is only once
the
| > > | > > application was migrated to 2.0 that the errors began. And
they only
| > > happen
| > > | > > part of the time and almost seem related to the amount of form
data
| > > that
| > > | > > needs to be reposted?
| > > | > >
| > > | > > Any ideas how to correct or why the errors only occur part of
the
| > > time etc.
| > > | > > I will probably try turning off eventvalidation to see if that
is the
| > > reason
| > > | > > since it is difference i can see in the data that is posted
back.
| > > | > >
| > > | > >
| > > | > > (Code for formredirect.aspx - aspx file is blank and the below
| > > generates all
| > > | > > of the html).
| > > | > >
| > > | > > Public Sub OutputFormData()
| > > | > > Response.Write("<!DOCTYPE html PUBLIC ""-//W3C//DTD
XHTML
| > > 1.0
| > > | > > Transitional//EN""
| > > | > > ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" +
| > > Chr(10))
| > > | > > Response.Write("<html lang=""en"">" + Chr(10))
| > > | > > Response.Write(" <head>" + Chr(10))
| > > | > > Response.Write(" <title>See Spot Reload the
| > > Form!!!</title>" +
| > > | > > Chr(10))
| > > | > > Response.Write(" </head>" + Chr(10))
| > > | > > Response.Write(" <body bgcolor=""#ffffff"">" +
Chr(10))
| > > | > > Response.Write(" <div id=""showprogress""
| > > style=""DISPLAY:
| > > | > > inline; VISIBILITY: visible; WIDTH: 100%; POSITION:
absolute"">" +
| > > Chr(10))
| > > | > > Response.Write(" <p align=""center""><img
| > > | > > src=""globalimages/transp.gif"" width=""5"" height=""50""><br>"
+
| > > Chr(10))
| > > | > > Response.Write(" <font face=""verdana""
size=""4""
| > > | > > color=""#ffcc66""><b>Resubmitting Original Request...Please
| > > | > > Wait...</b></font><br><br>" + Chr(10))
| > > | > > Response.Write(" <img
| > > | > > src=""globalimages/progressbarslower.gif""><br>" + Chr(10))
| > > | > > Response.Write(" <font face=""verdana""
| > > color=""#dddddd""
| > > | > > size=""1"">This may take a few moments...</font><br><br>" +
Chr(10))
| > > | > > Response.Write(" <a href=""mainmenu.aspx""><font
| > > | > > face=""verdana"" size=""2"" color=""#ffcc66""><b>Cancel &
Return to
| > > Main
| > > | > > Menu</b></font></a></p></div>" + Chr(10))
| > > | > >
| > > | > > If (Not (Request.Cookies("widsplusformkey") Is
Nothing)
| > > AndAlso
| > > | > > Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
| > > | > >
| > >
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Val
| > > ue) Is Nothing)) Then
| > > | > > Dim rf As Specialized.NameValueCollection =
| > > | > >
| > >
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey"
| > > ).Value), Specialized.NameValueCollection)
| > > | > >
| > > | > > Response.Flush()
| > > | > > If Not (rf Is Nothing) Then
| > > | > > Response.Write("<form name=""Form1""
| > > method=""post""
| > > | > > action=""" +
FormsAuthentication.GetRedirectUrl(User.Identity.Name,
| > > False) +
| > > | > > """ id=""Form1"">" + Chr(10))
| > > | > > For i As Integer = 0 To rf.Count - 1
| > > | > > Response.Write("<input type=""hidden""
| > > name=""" +
| > > | > > rf.GetKey(i) + """ id=""" + rf.GetKey(i) + """ value=""" +
rf.Item(i)
| > > + """>"
| > > | > > + Chr(10))
| > > | > > Next
| > > | > > Response.Write("</form>" + Chr(10) +
"<script
| > > | > > language=javascript>" + Chr(10) +
| > > "window.document.forms['Form1'].submit()" +
| > > | > > Chr(10) + "</script>" + Chr(10))
| > > | > > Response.Write(" </body>")
| > > | > > Response.Write("</html>")
| > > | > > ' clear the saved post data
| > > | > >
| > > | > >
| > >
System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey
| > > ").Value)
| > > | > > Response.Cookies("widsplusformkey").Value =
""
| > > | > > Response.Cookies("widsplusformkey").Path =
| > > "/widsplus"
| > > | > > End If
| > > | > > Else
| > > | > > Response.Write(" </body>")
| > > | > > Response.Write("</html>")
| > > | > > Response.Cookies("widsplusformkey").Value = ""
| > > | > > Response.Cookies("widsplusformkey").Path =
"/widsplus"
| > > | > >
| > > | > >
| > >
Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
| > > | > > False))
| > > | > > End If
| > > | > > End Sub
| > > |
| > >
| > >
|
 
G

Guest

Hi Steven,

Thanks for your reply. The only remaining response.write statements were to
write out a div with a "progress bar" type message since the page we post to
might be a search page or other long-running page. I don't see how that
would cause an issue. However, I've changed it to also dynamically use a
literal control.

However, I still get the same error when the form posts itself to the
original page. I think you might not understand what I am trying to do.
Here is the sequence of actions from the user viewpoint.

1) They click an action button on a form they are on that we will call
dosomething.aspx.
2) Their session had timed out so ASP.NET redirects them to the login page.
In global.asax, I cache their entire Request.Form object to preserve any
information they had keyed that would otherwise now be lost.
3) The login page redirects them to formredirection.aspx when they login.
4) On formredirection.aspx, I construct a form with hidden form fields
holding the data that I had cached for the user - the data the user
originally posted to dosomething.aspx.
5) Form redirection changes its action tag and posts itself back to
dosomething.aspx
6) Dosomething.aspx sees the post request and takes that posted information
to populate its controls...i.e. viewstate and control state is restored back
to what it was in step 1. From the user point of view they have now gone
back with all their data intact.

The method I used in 1.1 required no modifications to the dosomething.aspx
page of which there are several hundred in the application.

Cross page posting does not work for this scenario because it stores the
form data of the original page in the "Previouspage" collection. It does not
restore the form data to the posted page and it is really just another method
of persisting information from one page to another.

Cross page posting would require me to add code to each of the pages of the
application (the dosomething.aspx) pages so that they would look at the
previouspage collection and use that data to rebuild their own control state
and form data values.

I've made several more modifications to my original code which is below.
The aspx page now has almost nothing on it other than a form tag. I prefer
not to use inline method for the page since everything else in the
application is code-behind and i prefer that model.

Thx.
R-


Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If (Page.IsPostBack) Then
Exit Sub ' Should not ever happen
End If
If (Not (Request.Cookies("widsplusformkey") Is Nothing) AndAlso
Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value) Is Nothing)) Then
Dim rf As Specialized.NameValueCollection =
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Value), Specialized.NameValueCollection)

If Not (rf Is Nothing) Then
' Clear the saved post data

System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey").Value)
' Clear cookies
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"
' Output progress indicator
Dim hcontrol As New LiteralControl

hcontrol.ID = "showprogress"
hcontrol.Text = "<div style=""WIDTH: 100%; POSITION:
absolute; text-align: center; font-family: verdana""><img
src=""globalimages/transp.gif"" width=""5"" height=""50""><br><font
size=""4"" color=""#ffcc66""><b>Resubmitting Original Request...Please
Wait...</b></font><br><br><img
src=""globalimages/progressbarslower.gif""><br><font color=""#dddddd""
size=""1"">This may take a few moments...</font><br><br><a
href=""mainmenu.aspx""><font size=""2"" color=""#ffcc66""><b>Cancel & Return
to Main Menu</b></font></a></div>"
Page.Form.Controls.Add(hcontrol)

' Construct form dynamically
Page.Form.ID = "Form1"
Page.Form.Name = "Form1"
Page.Form.Method = "post"

For i As Integer = 0 To rf.Count - 1
If (rf.GetKey(i).Length < 2 OrElse
rf.GetKey(i).Substring(0, 2) <> "__") Then
Dim control As New HiddenField()

control.ID = rf.GetKey(i)
control.Value = rf.Item(i)
Page.Form.Controls.Add(control)
End If
Next
ClientScript.RegisterStartupScript(GetType(String),
"postform", "<script
language=""javascript"">window.document.forms['Form1'].action=""" +
FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) + """;\\
window.document.forms['Form1'].submit();</script>")
End If
Else
Response.Cookies("widsplusformkey").Value = ""
Response.Cookies("widsplusformkey").Path = "/widsplus"

Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
False))
End If
End Sub
 
S

Steven Cheng[MSFT]

Thanks for your followup Robert,

So I got some further info on your scenario. But seems manually inject HTML
( using Literalcontrol.Text ) is not a good idea. Also, I noticed that you
still have registered the following script :

================
<script
language=""javascript"">window.document.forms['Form1'].action=""" +
FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) + """;\\
window.document.forms['Form1'].submit();</script>")
==============

Well, this is also some manaual cross page post scripts(which is not
generated through buildin api...), so when you post to the

FormsAuthentication.GetRedirectUrl(User.Identity.Name, False)

page, that page will throw ViewState validation exception ..... So, we'd
better always using FormsAuthentication.RedirectFromLoginpage.... or
Response.Redirect in server code....... and avoid the above script
injecting (which change the form's action attribute and manually submit...)


In addition, as for storeing some form data before and after the user login
in, I think you can have a look at the new Profile service feature in
ASP.NET 2.0. The Profile service can help us to store some user specific
data in some persistent storage(sqlserver .... which is provider
based...). Also, when we turn on anonymousIdentification , we can also use
such service to store data for each anonymous user , and when the user
login, we can use Profile Service's Migration event to merge the anonymous
data into the user's login user's data store....

For detailed info on Profile service, you can refer to the following
reference:

#Storing User Profiles
http://66.129.71.130/QuickStartv20/aspnet/doc/profile/default.aspx

#Storing User Information with ASP.NET 2.0 Profiles
http://msdn.microsoft.com/library/en-us/dnvs05/html/userprofiles.asp?frame=t
rue

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)









--------------------
| Thread-Topic: Viewstate issues after move to 2.0 from 1.1
| thread-index: AcXxDjdR6pPCKH9pSKeSOFDDpWGvZQ==
| X-WBNR-Posting-Host: 67.180.214.235
| From: =?Utf-8?B?Um9iZXJ0?= <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]> <E3B11132-B915-4C5A-B073-C2F75C
(e-mail address removed)> <[email protected]>
<[email protected]>
| Subject: RE: Viewstate issues after move to 2.0 from 1.1
| Date: Thu, 24 Nov 2005 07:46:21 -0800
| Lines: 183
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet:360763
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Hi Steven,
|
| Thanks for your reply. The only remaining response.write statements were
to
| write out a div with a "progress bar" type message since the page we post
to
| might be a search page or other long-running page. I don't see how that
| would cause an issue. However, I've changed it to also dynamically use a
| literal control.
|
| However, I still get the same error when the form posts itself to the
| original page. I think you might not understand what I am trying to do.
| Here is the sequence of actions from the user viewpoint.
|
| 1) They click an action button on a form they are on that we will call
| dosomething.aspx.
| 2) Their session had timed out so ASP.NET redirects them to the login
page.
| In global.asax, I cache their entire Request.Form object to preserve any
| information they had keyed that would otherwise now be lost.
| 3) The login page redirects them to formredirection.aspx when they login.
| 4) On formredirection.aspx, I construct a form with hidden form fields
| holding the data that I had cached for the user - the data the user
| originally posted to dosomething.aspx.
| 5) Form redirection changes its action tag and posts itself back to
| dosomething.aspx
| 6) Dosomething.aspx sees the post request and takes that posted
information
| to populate its controls...i.e. viewstate and control state is restored
back
| to what it was in step 1. From the user point of view they have now gone
| back with all their data intact.
|
| The method I used in 1.1 required no modifications to the
dosomething.aspx
| page of which there are several hundred in the application.
|
| Cross page posting does not work for this scenario because it stores the
| form data of the original page in the "Previouspage" collection. It does
not
| restore the form data to the posted page and it is really just another
method
| of persisting information from one page to another.
|
| Cross page posting would require me to add code to each of the pages of
the
| application (the dosomething.aspx) pages so that they would look at the
| previouspage collection and use that data to rebuild their own control
state
| and form data values.
|
| I've made several more modifications to my original code which is below.
| The aspx page now has almost nothing on it other than a form tag. I
prefer
| not to use inline method for the page since everything else in the
| application is code-behind and i prefer that model.
|
| Thx.
| R-
|
|
| Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
| System.EventArgs) Handles MyBase.Load
| 'Put user code to initialize the page here
| If (Page.IsPostBack) Then
| Exit Sub ' Should not ever happen
| End If
| If (Not (Request.Cookies("widsplusformkey") Is Nothing)
AndAlso
| Request.Cookies("widsplusformkey").Value <> "" AndAlso Not
|
(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey").Val
ue) Is Nothing)) Then
| Dim rf As Specialized.NameValueCollection =
|
CType(System.Web.HttpContext.Current.Cache(Request.Cookies("widsplusformkey"
).Value), Specialized.NameValueCollection)
|
| If Not (rf Is Nothing) Then
| ' Clear the saved post data
|
|
System.Web.HttpContext.Current.Cache.Remove(Request.Cookies("widsplusformkey
").Value)
| ' Clear cookies
| Response.Cookies("widsplusformkey").Value = ""
| Response.Cookies("widsplusformkey").Path = "/widsplus"
| ' Output progress indicator
| Dim hcontrol As New LiteralControl
|
| hcontrol.ID = "showprogress"
| hcontrol.Text = "<div style=""WIDTH: 100%; POSITION:
| absolute; text-align: center; font-family: verdana""><img
| src=""globalimages/transp.gif"" width=""5"" height=""50""><br><font
| size=""4"" color=""#ffcc66""><b>Resubmitting Original Request...Please
| Wait...</b></font><br><br><img
| src=""globalimages/progressbarslower.gif""><br><font color=""#dddddd""
| size=""1"">This may take a few moments...</font><br><br><a
| href=""mainmenu.aspx""><font size=""2"" color=""#ffcc66""><b>Cancel &
Return
| to Main Menu</b></font></a></div>"
| Page.Form.Controls.Add(hcontrol)
|
| ' Construct form dynamically
| Page.Form.ID = "Form1"
| Page.Form.Name = "Form1"
| Page.Form.Method = "post"
|
| For i As Integer = 0 To rf.Count - 1
| If (rf.GetKey(i).Length < 2 OrElse
| rf.GetKey(i).Substring(0, 2) <> "__") Then
| Dim control As New HiddenField()
|
| control.ID = rf.GetKey(i)
| control.Value = rf.Item(i)
| Page.Form.Controls.Add(control)
| End If
| Next
| ClientScript.RegisterStartupScript(GetType(String),
| "postform", "<script
| language=""javascript"">window.document.forms['Form1'].action=""" +
| FormsAuthentication.GetRedirectUrl(User.Identity.Name, False) + """;\\
| window.document.forms['Form1'].submit();</script>")
| End If
| Else
| Response.Cookies("widsplusformkey").Value = ""
| Response.Cookies("widsplusformkey").Path = "/widsplus"
|
| Response.Redirect(FormsAuthentication.GetRedirectUrl(User.Identity.Name,
| False))
| End If
| End Sub
|
| "Steven Cheng[MSFT]" wrote:
|
| > Hey Robert,
| >
| > Thanks for your quick response.
| > From your further description and the code snippet you provided, seems
| > you're still using the Response.Write .... means to output page
content(
| > this is usually what the old ASP or other scripting based dynamic
document
| > use...). Is it possible that we change to utilize the ASP.NET server
| > control model , using Response.Write is really not a good idea. I'd
rather
| > recommend you just clear up the ASPX's content and using the following
code
| > block inline (as classic ASP do)
| >
| > <%@page .....%>
| >
| > <%
| >
| > //all code here
| >
| > %>
| >
| >
| > Also, as for your problem on
| > ===================
| > The moment I use the code at the end of the below where the script
changes
| > the form action for postback to the original page (prior to the user
having
| > timed-out), then i end up with the viewstate error.
| > ===================
| >
| > if you're using the new ASP.NET control model, you 'll find that
ASP.NET
| > 2.0 provide "CrossPage Posting" functionality which help us to easily
post
| > from one aspx page to another (we don't need to manually change the
html
| > form's action attribute...), what we need to do is changing the Button
| > Control's PostBackUrl property , like:
| >
| > protected void RadioButton_CheckedChanged(object sender, EventArgs e)
| > {
| > RadioButton rb = (RadioButton)sender;
| >
| > if (rb == RadioButton1)
| > {
| > btnPostBack.PostBackUrl = "~/AccessTestPage.aspx";
| > }
| > else
| > {
| > btnPostBack.PostBackUrl = "~/FtpWebPage.aspx";
| > }
| > }
| >
| >
| > #Cross-Page Posting in ASP.NET Web Pages
| > http://msdn2.microsoft.com/en-us/library/ms178139.aspx
| >
| >
| > In addition, as for storing form's post data for later use, I think
this is
| > done by default for ASP.NET page (if viewstate enabled), most of each
| > server control's properties will be persisted in ViewState for
sequential
| > postback use... However, when there occurs timeout, of course, this
is an
| > exceptional scenario, we need to write our own code to handel it (e.g
store
| > them in cache or any other storage and reset them to asp.net page's
| > controls properties later....). Again this require that we utilize the
| > ASP.NET page control model ....
| >
| > Thanks,
| >
| > Steven Cheng
| > Microsoft Online Support
| >
|
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top