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?= <ro*****@noemail.nospam>
| References: <82**********************************@microsoft.co m>
<C3**********************************@microsoft.co m>
<C6**********************************@microsoft.co m>
<$1*************@TK2MSFTNGXA02.phx.gbl>
<E3**********************************@microsoft.co m>
| 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: <84**********************************@microsoft.co m>
| 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!TK2MSFT NGXA03.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.Cook ies("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(Reques t.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(Str ing),
| "postform", "<script
| language=""javascript"">window.document.forms['Form1'].action=""" +
| FormsAuthentication.GetRedirectUrl(User.Identity.N ame, False) +
| """;window.document.forms['Form1'].submit();</script>")
| End If
| Else
| Response.Cookies("widsplusformkey").Value = ""
| Response.Cookies("widsplusformkey").Path = "/widsplus"
|
| Response.Redirect(FormsAuthentication.GetRedirectU rl(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(contr ol.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==?="
| > > <Ph**************@webswapp.com>
| > > | References: <82**********************************@microsoft.co m>
| > > <C3**********************************@microsoft.co m>
| > > | 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: <C6**********************************@microsoft.co m>
| > > | 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="447C05E8B3A71401CC4CAE5513A7F1A3494 A3618EE819316AAD1D58433F23
| > > 6A759D66FB4154500E01EB4E1BC1DE42046E2D652D391CB836 7A1649438867A02EB"
| > > | > >
decryptionKey="CE8D47C43312A144B49DE5E8D3D3CA2CDEA 230077AFB86CB"
| > > | > > 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(guidstrin g,
| > > | > > 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.Cook ies("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.N ame,
| > > 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(Reques t.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.GetRedirectU rl(User.Identity.Name,
| > > | > > False))
| > > | > > End If
| > > | > > End Sub
| > > |
| > >
| > >
|