2007年11月12日

ViewState壓縮相容於UpdatePanel (VB.NET版本)

在網路上有關.NET的ViewState壓縮的程式碼相當多,
但是當我們將它應用於AJAX的專案時,我們發現了,使用UpdatePanel時,若有存取ViewState,則會造成取不到ViewState的窘境。
為此我們重新在Google上找尋了另外的版本加以改進。
下面這一段Code的ViewState壓縮將可以相容於UpdatePanel摟~~
(不過有一個缺點,就是壓縮效果比較差就是了...)

使用方法:直接將下面的Code複製至Page裡面,就可以了。不用任何的引用與觸發。

相關原理就不多做說明了,如果有網友想要知道其相關撰寫原理,再另外留言吧!我再進行整理發表。


'''
''' 壓縮
'''

'''
'''
'''
Private Function Compress(ByVal data() As Byte) As Byte()
Dim ms As New MemoryStream
Dim stream As New GZipStream(ms, CompressionMode.Compress)
stream.Write(data, 0, data.Length)
stream.Close()
Return ms.ToArray
End Function

'''
''' 解壓縮
'''

'''
'''
'''
Public Function Decompress(ByVal data() As Byte) As Byte()
Dim ms As New MemoryStream
ms.Write(data, 0, data.Length)
ms.Position = 0
Dim stream As New GZipStream(ms, CompressionMode.Decompress)
Dim temp As New MemoryStream
Dim buffer(1024) As Byte
While True
Dim read As Integer = stream.Read(buffer, 0, buffer.Length)
If read <= 0 Then
Exit While
Else
temp.Write(buffer, 0, read)
End If
End While
stream.Close()
Return temp.ToArray
End Function

Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal state As Object)
Dim pair As Pair
Dim persister As PageStatePersister = Me.PageStatePersister
Dim ViewState As Object
If TypeOf state Is Pair Then
pair = CType(state, Pair)
persister.ControlState = pair.First
ViewState = pair.Second
Else
ViewState = state
End If
Dim formatter As New LosFormatter
Dim writer As New StringWriter
formatter.Serialize(writer, ViewState)
Dim viewStateStr As String = writer.ToString()
Dim data As Byte() = Convert.FromBase64String(viewStateStr)
Dim compressedData As Byte() = Me.Compress(data)
Dim str As String = Convert.ToBase64String(compressedData)
persister.ViewState = str
persister.Save()
End Sub

Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
Dim persister As PageStatePersister = Me.PageStatePersister
persister.Load()

Dim viewState As String = persister.ViewState.ToString()
Dim data As Byte() = Convert.FromBase64String(viewState)
Dim uncompressedData As Byte() = Me.Decompress(data)
Dim str As String = Convert.ToBase64String(uncompressedData)
Dim formatter As New LosFormatter
Return New Pair(persister.ControlState, formatter.Deserialize(str))
End Function

4 則留言:

  1. 以小弟愚見....

    在解碼的地方可能有問題...

    原文是:
    temp.Write(buffer, 0, buffer.Length)

    應該是:
    temp.Write(buffer, 0, read)

    ........若有錯還請指點, 謝謝 ^ ^;;;

    回覆刪除
  2. 基本上這兩個數值會一樣
    因為下面這一段
    Dim read As Integer = stream.Read(buffer, 0, buffer.Length)

    回覆刪除
  3. 不會的...

    Dim read As Integer = stream.Read(buffer, 0, buffer.Length)

    這段會取得 實際讀取的長度
    然後將值給 read

    所以才需要改為

    temp.Write(buffer, 0, read)

    ..............指定寫入temp 的長度為 read 而非 buffer.Length

    您可以試試看....

    結果會有些差別...

    回覆刪除
  4. sorry...

    剛剛仔細再看了一次程式碼,您說的沒有錯!
    是我之前搞錯了!
    已經修正了原文...

    Blog內,若有其他錯誤的地方,再煩請指教!
    感謝!

    回覆刪除