(ASP.NET) ASP.NET (2005 год)

Хранение состояния страниц на сервере

Для того, чтобы увидеть ViewState своей странички, достаточно в Page_load записать:

00001:     If Not (Me.Request.Form("__VIEWSTATE")) Is Nothing Then
00002:         Session("ViewState") = Me.Request.Form("__VIEWSTATE")
00003:     End If

А в Prerender:

00001:     If Not (Session("ViewState") Is Nothing) Then
00002:         Dim X() As Byte = Convert.FromBase64String(Session("ViewState"))
00003:         Panel3.Controls.Add(New LiteralControl(System.Text.Encoding.ASCII.GetString(X)))
00004:         Panel3.Controls.Add(New LiteralControl("<BR><BR><BR>"))
00005:         Dim Z As New LosFormatter
00006:         Dim A As Object = Z.Deserialize(Session("ViewState").ToString.Replace("\n", "").Replace("\r", ""))
00007:     End If

Тогда на страничке мы увидет что-то вроде:

? -1512249231dfddddd PostBackUrl~/Link/Page1_LoadStart.aspxdd NavigateUrl~/Link/Page1_LoadStart.aspxdd~/Link/Page1_Filter.aspxdd~/Link/Page1_Filter.aspxdd~/Link/Page1_Filter.aspxdd~/Link/Page1_Filter.aspxdd _!DataBoundgd      C????????1gIPOD2g.???????????????????? ?????? ??????????????????3g=???????????????????? ?? ?????????????????? ??????????????????4g????????????????????5g??????????, ??????????6g!???????????????????????? ????????7g????????8g????????????????9g??????????????????????????10g????????????????????11g ????????????12g????????????????13g 

C помощью класса Pair и Triplets можно полностью разобрать ViewState в полную древовидную структуру, но у меня это не получается, тк LosFormatter.Deserialize упрямо пишет "The serialized data is invalid.



Для облегчения участи клиентов, которые забрели на ваш ASP2-сайт, ViewState рекомендуется хранить на сервере (в базе или кеше). Делается это вроде бы вот таким простейшим способом:

00001:     Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal state As Object)
00002:         'MyBase.SavePageStateToPersistenceMedium(state)
00003:         Session("ViewState#") = state
00004:     End Sub
00005: 
00006:     Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
00007:         'Return MyBase.LoadPageStateFromPersistenceMedium()
00008:         Return Session("ViewState#")
00009:     End Function

Однако так при пейжинге таблы получается ошибка. Цепляться за SessionID также нельзя, так как, как это не неожиданно, он может меняться (пока к нему не было обращений). Наиболее надежным вариантом на практике оказывается создание собственного ключа и сохранение его на страничке:

00001:     Protected Overrides Sub SavePageStateToPersistenceMedium(ByVal state As Object)
00002:         'создали уникальный ключ и его вписали вместо самого ViewState, а сам ViewState оставили у себя в кеше
00003:         Dim Key As String = "Page1#" & Request.UserHostAddress & "#" & DateTime.Now.Ticks.ToString()
00004:         Cache.Add(Key, State, Nothing, DateTime.Now.AddMinutes(Session.Timeout), TimeSpan.Zero, CacheItemPriority.NotRemovable, Nothing)
00005:         ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", Key)
00006:     End Sub
00007: 
00008:     Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
00009:         Dim Key As String = Request.Form("__VIEWSTATE_KEY")
00010:         If Key.StartsWith("Page1#") Then
00011:            If Cache.Get(Key) Is Nothing Then
00012:                Throw New Exception("Кеш утерян: " + Key)
00013:            Else
00014:                Return Cache.Get(Key)
00015:            End If
00016:         Else
00017:            Throw New Exception("ViewState испорчен: " + Key)
00018:         End If
00019:     End Function

С таким же ключом это можно ложить и в базу и триггером удалять устаревшие записи. Что конечно медленнее, зато гораздо надежнее. Вообще-то кеш в ASP2 работает плохо, записи теряет только так и при недостатке памяти он потеряется все равно. (При работе с кешем, учтите, что отладчик кеш просматривать не умеет, помочь может это).



Comments ( )
Link to this page: //www.vb-net.com/asp2/4/index.htm
< THANKS ME>