2009-08-03 85 views
2

是否可以序列化ASP.NET Web表單,包括用戶輸入的所有數據?我想讓用戶能夠保存一個半完成的表單,並希望我可以通過序列化來完成。任何簡單的例子將不勝感激。序列化ASP.NET Web表單

編輯: 我想避免必須具有單獨的數據圖層的「不完整」的形式,鏡像層完成的形式。我不想將不完整的表格與完整的表格一起存儲,因爲它們可能無法通過我的數據庫限制。

+1

爲什麼這次被拒絕? – Jason 2009-08-13 16:49:03

+0

您不想爲不完整的表單單獨存儲數據,也不希望將它們存儲在完整的表單中。那麼你想如何以及在哪裏存儲它們? – LukeH 2009-08-13 16:54:44

+0

爲清晰起見進行了編輯。對不起盧克。 – 2009-08-13 16:57:09

回答

4

對於不完整的表單,您無法避免使用單獨的存儲位置。您需要將它們保存在某個位置,並且不能將它們放在完整的位置,因爲顯然您對底層數據庫表有一些數據庫限制,並且希望保留它們。我會建議@Ramesh將表單的數據封裝在一個類中。

public class FormData 
{ 
    public int IntField { get;set;} 
    public string StringField {get;set;} 
    public decimal DecimalField {get;set;} 
    public decimal DateTimeField {get;set;} 
} 

將FormData對象綁定到您的UI控件。當用戶想要保存不完整的數據時,將FormData對象序列化爲xml,因爲您確實想在此處使用序列化。

XmlSerializer serializer = new XmlSerializer(typeof(FormData)); 
StringWriter writer = new StringWriter(new StringBuilder()); 
serializer.Serialize(writer,formDataObject); 
string serializedFormDataObject = writer.GetStringBuilder().ToString(); 

然後,您可以將serializedFormDataObject保存到單獨的表。當用戶加載表單時,可以檢查表格以查看錶單是否不完整。如果是,您可以反序列化表單加載事件中的數據,例如:

string serializedFormDataObject = GetFromDatabase(formId,userId); //you get the idea I guess 
StringReader reader = new StringReader(serializedFormDataObject); 
XmlSerializer serializer = new XmlSerializer(typeof(FormData)); 
formDataObject = serializer.Deserialize(reader) as FormData; 

然後,您可以將formData綁定到您的控件。完成表格後,您可以刪除不完整的表格條目,並將完成的表格保存到已完成表格的表格中。

8

麥克,

你不必序列化整個asp.net形式捕獲半滿的數據。它更好地捕獲在卸載(或觸發器)字段中輸入的數據並將其保存在數據庫中。和u只需將數據重新分配到控制,同時又加載頁面..這是不是序列化整個頁面更好...

編輯::

按照烏拉圭回合的一些意見我明白在這後,UR要求是

  • 堅持半填充數據資料完整
  • 沒有一起和UR數據非常敏感
  • 和u要存儲PA的序列化形式GE並使其 直接whenener需要...

但做ü想進行序列化在這方面recommented,它會解決所有問題烏爾.. NO ..

考慮以下事實

  1. 如果你正在序列化整個 表格,你最終可能會存儲那些甚至不需要的數據 。 (如果您的 表單包含15個文本框,並且用戶 剛剛只填充了2個條目,則使用表格對象持續存在整個 )。
  2. 並且傳輸的數據量將會更高 (增加數據包大小,減慢傳輸速率)。
  3. 而你對頁面的控制(要從序列化的 對象渲染)較少。考慮,如果你想 上顯示 一些通知的序列化形式..療法可能是 某種方式來做到這一點是肯定的..但我 知道它不是那麼簡單..

考慮給出的所有事實通過脂肪酶在這裏誰在這個有經驗,做了一些分析urself和選擇最好的方法..所有的最好的

編輯

我對面的JQuery AutoSave插件來了..和其做同樣的我sugge st,但是以一種相當簡單的方式......(其在指定的一段時間間隔&中保存未保存的內容。你可以輕鬆地調整這個以滿足你的需求)只要看看..

+0

似乎是一個可行的選擇。除非有人提出更好的答案,否則一律同意。 – 2009-08-03 05:17:32

+1

我想探索序列化的選項。這就是我的問題的具體內容。 – 2009-08-03 13:13:03

1

你說你想要序列化處於部分完成狀態的表單。從您的問題和各種評論中,您聽起來像是在嘗試使用序列化來避免使用單獨的存儲。但是,這不是系列化的內容。

序列化將通常在內存中的某個對象轉換爲已知格式(例如XML文件),以便它可以通過網絡傳輸或保存在數據庫中。序列化並不意味着什麼做什麼與一個對象以其序列化的形式,只有它是一個序列化的形式。

很抱歉,如果這是千篇一律的,但我認爲它是由非常清楚:http://en.wikipedia.org/wiki/Serialization

編輯:也許你明白我說的上面已經 - 你要買,例如,把序列化的形式進入會議?

編輯2:好吧,我想我明白了。您可以將序列化表單保存到數據庫中,但不希望將單個表單輸入保存到數據庫中 - 就像保存完整表單一樣。所以,你正在尋找一種方式來保持不完整的形式不同於完成的。 爲此,我會在您的數據庫中爲此確定一個新表。它可以有一個單一的數據列(存儲序列化數據)或與正常(完成表格)表相同的列,而沒有你提到的限制。這有意義嗎?

+0

我明白什麼是序列化。我正在尋找一種簡單的方法來獲取我的頁面狀態,將它包裝成一個球,並將其保存到數據庫中,假設它永遠不會用於任何其他原因,使其恢復到頁面有一點。我認爲序列化對於這樣的事情是一個很好的,容易的選擇。我願意接受其他更簡單的想法。 – 2009-08-13 04:27:40

0

序列化不會對你有所幫助,除非你很樂意在別的地方存儲已被使用過的數據,可能是作爲db表中的xml片段或作爲文件(yuk)。 這似乎是對我錯誤的方法,但如果你真的想要使用序列化有很多選擇。我能想到的最簡單的方法是將request.form集合序列化爲xml,可以通過使用xmlserializer或通過循環來構建xml字符串。

我的建議是...

如果你樂於使用的JavaScript,爲什麼不嘗試做這個客戶端上?

你可以收集一個「保存」按鈕的點擊,例如從表單中的數據並將其保存在cookie中。

當用戶回來,您可以檢查此Cookie,並從cookie重新加載數據。

當表單完成時,您只能將表單數據發送回服務器。這將避免你的DB約束問題。

試試這個:http://www.bigresource.com/Tutorial/PHP/Saving_Form_Data_Into_A_Cookie.htm

UPDATE

以下意見: OK,如果你想利用的方法序列化表單你需要存儲一些數據。

基於我認爲你想做的事:

如果你的表單數據在一個單一的表適合我建議你有一個「副本表」,不分貝的限制,並調用它像formDataHolding(你的原始文件是fomrData)。你可以從這個表中讀寫,並且只在表單數據完成時才遷移數據,我使用遷移這個詞來表示數據離開保存表並以某種方式進入完整表。 如果您的表單包含適合多個表格的數據,那麼序列化可能是正確的答案,但要做好準備將這些數據存儲到某個地方,這種方式可能無法與您現有的數據模型保持一致,或者準備創建「副本表「沒有約束,對於所有存儲數據的表。

序列化的數據並不necassarily意味着你正在創建XML,但我認爲這是你想要的。我會採取從Request.Form獲取NameValueCollection然後序列化它的方法。如果您使用網絡表單,您可能想要做到這一點。

這裏是人誰序列化NameValueCollection中的URL: http://nayyeri.net/blog/Serialize-NameValueCollection/

0

考慮爲google gears,它允許用戶離線工作發展。基本上,這意味着表單數據在本地保存直到承諾服務器。雖然谷歌本身對增強微軟開發人員的權力並不感興趣,但開發人員社區中有這些人。這是一個tutorial關於讓ASP.NET應用程序利用谷歌齒輪。

0

我沒有經歷過這麼大的答案,但我看起來像去只需要堅持視圖狀態和使用持續的視圖狀態,而不是建立在需要時半進入新的形式之一。

無需任何額外的邏輯,ViewState是設計用來就像這樣。

任何回發在技術上是新的頁面渲染,但是從視圖狀態和運算使用值正好試圖做同樣的事情,只是不回發,但一些其他的時間,但需要同樣的事情

1

ViewState是不幸的是不夠的;您還需要考慮發佈數據和查詢參數,以便能夠準確保存和恢復頁面狀態。 Here是關於涉及的問題的非常全面的寫作,它包括工作代碼。

0

我採用了多種形式(主要是多頁但同樣適用於單頁)的方法是爲每個表單頁從具有多個屬性的公共基類繼承。其中一個屬性是FormData,可以定義爲:

public FormData FormDataStore 
{ 
    get 
    { 
     if (Session["FormDataStore"] == null) 
     { 
      Session["FormDataStore"] = new FormData(); 
     } 

     return (FormData)Session["FormDataStore"]; 
    } 
    set 
    { 
     Session["FormDataStore"] = value; 
    } 
} 

FormData是一個保存所有屬性(表單的字段)的類,例如,

public class FormData 
{ 
    public string name {get; set;} 
    public string email {get; set;} 
} 

每個表單頁面有一個「LoadData」和「保存數據」功能,其負責與來自FormDataObject對象數據填充的形式,並且分別將數據保存到FormDataObject對象。

基類還包含2個方法SaveDraft和LoadDraft。 SaveDraft串行FormDataObject到XML和保存到DB表(其可以是作爲2列,ID和XMLDATA簡單):

  StringWriter sw_wf = new StringWriter(); 
      XmlSerializer xs_wf = new XmlSerializer(FormData.GetType(), new System.Type[] { typeof(additionalObjects)}); 
      xs_wf.Serialize(sw_wf, FormDataObject); 
      string WebFormData = sw_wf.ToString(); 
      sw_wf.Close(); 

      //write WebFormData to database 

LoadDraft簡單地加載XML和deserialises回對象,其形式會自動拾取填充和填充字段。 LoadDraft的工作方式取決於數據的性質和數據的敏感性 - 例如,如果表單由登錄用戶完成,或者它可能是匿名的,並且存儲在數據庫和cookie中的唯一ID。

我構建了很多提交給1個或多個Web服務的站點,這種方法在從WSDL文件構建存根並將其用作FormData類時非常有效。

0

過去使用的一種方法是從Form對象中捕獲POST值,並使用可使用soapformatter序列化的momemto類來存儲該值。當需要恢復時,我所做的只是通過查詢字符串參數來獲取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