我过去使用的一种方法是从表单对象中捕获 POST 值,并使用可以使用 soapformatter 序列化的 momemto 类存储该值。当需要恢复时,我所做的只是 GET 到带有查询字符串参数的 HttpHandler 类,该类解析预期的 id 并反序列化状态以进行恢复,从而呈现隐藏字段以模拟用户从原始页面发布帖子。这是两个类。
请注意,您正在捕获 FORM 的状态,因此当您恢复表单时,您会将状态恢复到您要求恢复的状态,如果您发现问题,您可能需要处理此问题。
''' <summary>
''' This class encapsulates the form state
''' </summary>
<Serializable()> _
Public NotInheritable Class FormState
Private _path As String
Private _form As NameValueCollection
''' <summary>
''' Constructor.
''' </summary>
''' <param name="path">The path of the original form post request.</param>
''' <param name="form">The form to save.</param>
Public Sub New(ByVal path As String, ByVal form As NameValueCollection)
_path = path
_form = form
End Sub
''' <summary>
''' Serializer Ctor.
''' </summary>
''' <remarks></remarks>
Sub New()
End Sub
''' <summary>
''' The path of the original form post request.
''' </summary>
Public ReadOnly Property Path() As String
Get
Return _path
End Get
End Property
''' <summary>
''' The saved form.
''' </summary>
Public ReadOnly Property Form() As NameValueCollection
Get
Return _form
End Get
End Property
End Class
''' <summary>
''' This http handler will render a small page that will reconstruct the form as it was before session timeout, using hidden fields.
''' The page will submit itself upon loading, meaning that the user will barely see it.
''' </summary>
Public Class FormStateRestoreHandler
Implements IHttpHandler, IRequiresSessionState
Private _state As FormState
Private _dealGuid As Guid
''' <summary>
''' The form state.
''' </summary>
Protected ReadOnly Property FormState() As FormState
Get
Return _state
End Get
End Property
''' <summary>
''' Gets a value indicating whether another request can use this IHttpHandler instance.
''' </summary>
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
''' <summary>
''' Processes the web request - this is where the page is rendered.
''' </summary>
''' <param name="context"></param>
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim Id = context.Request.QueryString("id")
If Id Is Nothing Then Return
_state = LoadFormState(Id)
Using writer As HtmlTextWriter = CreateHtmlTextWriter(context.Response.Output, context.Request.Browser)
Me.Render(writer)
End Using
End Sub
''' <summary>
''' Loads the specified FormState by id
''' </summary>
''' <param name="id">The unique id of the saved form state.</param>
''' <returns></returns>
Private Shared Function LoadFormState(ByVal id As Guid) As FormState
Dim _storageProvider = ConfigurationFacade.GetUnityContainer.Resolve(Of IDealProvider)()
Dim result As FormState = Nothing
Dim bytes = _storageProvider.LoadUserState(id)
Dim soapFormatter = New SoapFormatter
Using ms = New IO.MemoryStream(bytes)
result = soapFormatter.Deserialize(ms)
ms.Close()
End Using
Return result
End Function
''' <summary>
''' Renders a small page that will resubmit the saved form
''' </summary>
''' <param name="writer"></param>
Protected Overridable Sub Render(ByVal writer As HtmlTextWriter)
writer.RenderBeginTag(HtmlTextWriterTag.Html)
writer.RenderBeginTag(HtmlTextWriterTag.Head)
writer.RenderBeginTag(HtmlTextWriterTag.Title)
writer.Write("Restoring form")
writer.RenderEndTag()
' TITLE
writer.RenderEndTag()
' HEAD
writer.AddAttribute("onload", "document.forms[0].submit();")
writer.RenderBeginTag(HtmlTextWriterTag.Body)
writer.AddAttribute("method", "post")
writer.AddAttribute("action", Me.FormState.Path)
writer.RenderBeginTag(HtmlTextWriterTag.Form)
Dim form As NameValueCollection = Me.FormState.Form
For Each name As String In form.Keys
RenderHiddenField(writer, name, form(name))
Next
writer.AddAttribute(HtmlTextWriterAttribute.Align, "center")
writer.RenderBeginTag(HtmlTextWriterTag.P)
writer.Write("You should be redirected in a moment.")
writer.WriteFullBeginTag("br")
writer.Write("If nothing happens, please click ")
RenderSubmitButton(writer, "Submit")
writer.RenderEndTag()
' P
writer.RenderEndTag()
' FORM
writer.RenderEndTag()
' BODY
writer.RenderEndTag()
' HTML
End Sub
''' <summary>
''' Renders a hidden field.
''' </summary>
''' <param name="writer">The writer to use.</param>
''' <param name="name">The name of the hidden field.</param>
''' <param name="value">The value of the hidden field.</param>
Protected Shared Sub RenderHiddenField(ByVal writer As HtmlTextWriter, ByVal name As String, ByVal value As String)
writer.AddAttribute(HtmlTextWriterAttribute.Type, "hidden")
writer.AddAttribute(HtmlTextWriterAttribute.Name, name)
writer.AddAttribute(HtmlTextWriterAttribute.Value, value)
writer.RenderBeginTag(HtmlTextWriterTag.Input)
writer.RenderEndTag()
' INPUT
End Sub
''' <summary>
''' Renders a submit button.
''' </summary>
''' <param name="writer">The writer to use.</param>
''' <param name="text">The text of the button.</param>
Protected Shared Sub RenderSubmitButton(ByVal writer As HtmlTextWriter, ByVal text As String)
writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit")
writer.AddAttribute(HtmlTextWriterAttribute.Value, text)
writer.RenderBeginTag(HtmlTextWriterTag.Input)
writer.RenderEndTag()
' INPUT
End Sub
''' <summary>
''' Gets a HtmlTextWriter to write output to, based on a TextWriter.
''' </summary>
''' <param name="writer">The Text writer holding the output stream.</param>
''' <param name="browser">The browser capabilities of the client browser.</param>
''' <returns></returns>
Protected Shared Function CreateHtmlTextWriter(ByVal writer As TextWriter, ByVal browser As HttpCapabilitiesBase) As HtmlTextWriter
If browser Is Nothing Then
Return New HtmlTextWriter(writer)
End If
Return browser.CreateHtmlTextWriter(writer)
End Function
End Class