我在 DNN性能优化方案系列(1)概述 说明DNN对性能优化做的努力,Page State Persistence的保存方法是其中一个措施之一.
下面来看下DNN4.5.5的实现.
我在<<
DNN性能优化方案系列(1)概述 >>说明DNN对性能优化做的努力,Page State Persistence的保存方法是其中一个措施之一.
下面来看下DNN4.5.5的实现.
先看 DotNetNuke_04.05.05_Source\Library\Components\Framework\PageBase.vb
#Region "Protected Properties"
''' -----------------------------------------------------------------------------
''' <summary>
''' PageStatePersister returns an instance of the class that will be used to persist the Page State
''' </summary>
''' <returns>A System.Web.UI.PageStatePersister</returns>
''' <history>
''' [cnurse] 11/30/2005 Created
''' </history>
''' -----------------------------------------------------------------------------
Protected Overrides ReadOnly Property PageStatePersister() As System.Web.UI.PageStatePersister
Get
'Set ViewState Persister to default (as defined in Base Class)
Dim _persister As PageStatePersister = MyBase.PageStatePersister
If Not DotNetNuke.Common.Globals.HostSettings("PageStatePersister") Is Nothing Then
Select Case DirectCast(DotNetNuke.Common.Globals.HostSettings("PageStatePersister"), String)
Case "M"
_persister = New CachePageStatePersister(Me)
Case "D"
_persister = New DiskPageStatePersister(Me)
End Select
End If
Return _persister
End Get
End Property
#End Region
其中
Select Case DirectCast(DotNetNuke.Common.Globals.HostSettings("PageStatePersister"), String)
Case "M" '选择将页面状态持久化保存于内存,M即memery首字母
_persister = New CachePageStatePersister(Me)
Case "D" '选择将页面状态持久化保存于硬盘,D即Disk首字母,不过在主机设置里面似乎没有这个选项
_persister = New DiskPageStatePersister(Me)
End Select
CachePageStatePersister.vb
Imports System.Text


Namespace DotNetNukeNamespace DotNetNuke.Framework

''' -----------------------------------------------------------------------------
''' Namespace: DotNetNuke.Framework
''' Project: DotNetNuke
''' Class: CachePageStatePersister
''' -----------------------------------------------------------------------------
''' <summary>
''' CachePageStatePersister provides a cache based page state peristence mechanism
''' </summary>
''' <history>
''' [cnurse] 11/30/2006 documented
''' </history>
''' -----------------------------------------------------------------------------

Public Class CachePageStatePersisterClass CachePageStatePersister
Inherits PageStatePersister

''' -----------------------------------------------------------------------------
''' <summary>
''' Creates the CachePageStatePersister
''' </summary>
''' <history>
''' [cnurse] 11/30/2006 Documented
''' </history>
''' -----------------------------------------------------------------------------

Public Sub New()Sub New(ByVal page As Page)
MyBase.New(page)
End Sub

''' -----------------------------------------------------------------------------
''' <summary>
''' Loads the Page State from the Cache
''' </summary>
''' <history>
''' [cnurse] 11/30/2006 Documented
''' </history>
''' -----------------------------------------------------------------------------

Public Overrides Sub Load()Sub Load()

' Get the cache key from the web form data
Dim key As String = TryCast(Page.Request.Params("__VIEWSTATE_CACHEKEY"), String)

'Abort if cache key is not available or valid
If String.IsNullOrEmpty(key) Or Not key.StartsWith("VS_") Then
Throw New ApplicationException("Missing vaild __VIEWSTATE_CACHEKEY")
End If

Dim state As Pair = TryCast(DataCache.GetPersistentCacheItem(key, GetType(Pair)), Pair)

If Not state Is Nothing Then
'Set view state and control state
ViewState = state.First
ControlState = state.Second
End If

End Sub

''' -----------------------------------------------------------------------------
''' <summary>
''' Saves the Page State to the Cache
''' </summary>
''' <history>
''' [cnurse] 11/30/2006 Documented
''' </history>
''' -----------------------------------------------------------------------------

Public Overrides Sub Save()Sub Save()

'No processing needed if no states available
If ViewState Is Nothing And ControlState Is Nothing Then
Exit Sub
End If

Dim key As New StringBuilder()
Dim _PortalSettings As PortalSettings = PortalController.GetCurrentPortalSettings()
Dim TabId As Integer = _PortalSettings.ActiveTab.TabID

'Generate a unique cache key
With key
.Append("VS_")
.Append(IIf(Page.Session Is Nothing, Guid.NewGuid().ToString(), Page.Session.SessionID))
.Append("_")
.Append(TabId)
End With


'Save view state and control state separately
Dim state As New Pair(ViewState, ControlState)

'Add view state and control state to cache
DataCache.SetCache(key.ToString(), state, Nothing, DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration, True)

'Register hidden field to store cache key in
Page.ClientScript.RegisterHiddenField("__VIEWSTATE_CACHEKEY", key.ToString())

End Sub

End Class

End Namespace
继承PageStatePersister必须重载Load与Save
DNN将ViewState保存在内存,它将用于保存的Key保存的页面,用于从内存存取ViewState
Page.ClientScript.RegisterHiddenField("__VIEWSTATE_CACHEKEY", key.ToString())
生成一个隐藏域
<input type="hidden" name="__VIEWSTATE_CACHEKEY" id="__VIEWSTATE_CACHEKEY" value="VS_yjp0hlrgns3sqirbw0hsci45_36" />
此Key生成方法如下
With key
.Append("VS_")
.Append(IIf(Page.Session Is Nothing, Guid.NewGuid().ToString(), Page.Session.SessionID))
.Append("_")
.Append(TabId)
End With
并设置Cache过期时间为15分钟
DataCache.SetCache(key.ToString(), state, Nothing, DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration, True)
如果15分钟后页面才回传就会
Throw New ApplicationException("Missing vaild __VIEWSTATE_CACHEKEY")
就是这个页面的所有ViewState已经全部丢失.
这个Bug怎么处理,DNN不知有没有触觉的办法.我还没发现,或者目前根本还没解觉.
有好办法的同仁请提示下.
DiskPageStatePersister.vb
Imports System.IO
Imports System.Text


Namespace DotNetNukeNamespace DotNetNuke.Framework

''' -----------------------------------------------------------------------------
''' Namespace: DotNetNuke.Framework
''' Project: DotNetNuke
''' Class: DiskPageStatePersister
''' -----------------------------------------------------------------------------
''' <summary>
''' DiskPageStatePersister provides a disk (stream) based page state peristence mechanism
''' </summary>
''' <history>
''' [cnurse] 11/30/2006 documented
''' </history>
''' -----------------------------------------------------------------------------

Public Class DiskPageStatePersisterClass DiskPageStatePersister
Inherits PageStatePersister

''' -----------------------------------------------------------------------------
''' <summary>
''' Creates the DiskPageStatePersister
''' </summary>
''' <history>
''' [cnurse] 11/30/2006 Documented
''' </history>
''' -----------------------------------------------------------------------------

Public Sub New()Sub New(ByVal page As Page)
MyBase.New(page)
End Sub

''' -----------------------------------------------------------------------------
''' <summary>
''' The CacheDirectory property is used to return the location of the "Cache"
''' Directory for the Portal
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [cnurse] 11/30/2006 Created
''' </history>
''' -----------------------------------------------------------------------------

Public ReadOnly Property CacheDirectory()Property CacheDirectory() As String
Get
Return PortalController.GetCurrentPortalSettings.HomeDirectoryMapPath & "Cache"
End Get
End Property

''' -----------------------------------------------------------------------------
''' <summary>
''' The StateFileName property is used to store the FileName for the State
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [cnurse] 11/30/2006 Created
''' </history>
''' -----------------------------------------------------------------------------

Public ReadOnly Property StateFileName()Property StateFileName() As String
Get
Dim key As New StringBuilder()
With key
.Append("VIEWSTATE_")
.Append(Page.Session.SessionID)
.Append("_")
.Append(Page.Request.RawUrl)
End With
Return CacheDirectory & "\" & CleanFileName(key.ToString) & ".txt"
End Get
End Property

''' -----------------------------------------------------------------------------
''' <summary>
''' Loads the Page State from the Cache
''' </summary>
''' <history>
''' [cnurse] 11/30/2006 Documented
''' </history>
''' -----------------------------------------------------------------------------

Public Overrides Sub Load()Sub Load()

Dim reader As StreamReader = Nothing

' Read the state string, using the StateFormatter.
Try
reader = New StreamReader(StateFileName)

Dim serializedStatePair As String = reader.ReadToEnd

Dim formatter As IStateFormatter = Me.StateFormatter

' Deserialize returns the Pair object that is serialized in
' the Save method.
Dim statePair As Pair = CType(formatter.Deserialize(serializedStatePair), Pair)

ViewState = statePair.First
ControlState = statePair.Second
Finally
If Not reader Is Nothing Then
reader.Close()
End If
End Try

End Sub


''' -----------------------------------------------------------------------------
''' <summary>
''' Saves the Page State to the Cache
''' </summary>
''' <history>
''' [cnurse] 11/30/2006 Documented
''' </history>
''' -----------------------------------------------------------------------------

Public Overrides Sub Save()Sub Save()

'No processing needed if no states available
If ViewState Is Nothing And ControlState Is Nothing Then
Exit Sub
End If

If Not (Page.Session Is Nothing) Then
If Not Directory.Exists(CacheDirectory) Then
Directory.CreateDirectory(CacheDirectory)
End If

' Write a state string, using the StateFormatter.
Dim writer As New StreamWriter(StateFileName, False)

Dim formatter As IStateFormatter = Me.StateFormatter

Dim statePair As New Pair(ViewState, ControlState)

Dim serializedState As String = formatter.Serialize(statePair)

writer.Write(serializedState)
writer.Close()
End If
End Sub
End Class

End Namespace
在源码中看到的保存于盘硬的,没有过期这回事,但总不能让那些没用的文件一直留着,要有个删除的办法.但DNN中似乎还没处理这个.
还有这个Key问题,
''' -----------------------------------------------------------------------------
''' <summary>
''' The StateFileName property is used to store the FileName for the State
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [cnurse] 11/30/2006 Created
''' </history>
''' -----------------------------------------------------------------------------

Public ReadOnly Property StateFileName()Property StateFileName() As String
Get
Dim key As New StringBuilder()
With key
.Append("VIEWSTATE_")
.Append(Page.Session.SessionID)
.Append("_")
.Append(Page.Request.RawUrl)
End With
Return CacheDirectory & "\" & CleanFileName(key.ToString) & ".txt"
End Get
End Property
与比CachePageStatePersister.vb不周到的地方是他似乎没考虑Page禁用Session的情况.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章