The ASP.NET style web part does not have a partchache like the WSS 2.0 webpart. We needed a way to persist data long term.
Updates to properties from code do not persist unless you call SetPersonalizationDirty, but users with read permissions do not have sufficient rights to call this. One solution is below:
This code demonstrates how we can "cache" data into a web part's property from code. In our situation, data comes from a back-end system that is expensive to query and does not change often. The first time the web part runs, it caches its data into the DataCache property. Subsequent page loads display data from the property instead of the back-end system. Users can refresh the cache though the web part menu.
Imports System
Imports System.ComponentModel
Imports System.Configuration
Imports System.Data
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Xml
Imports Microsoft.SharePoint.WebPartPages
Imports Microsoft.SharePoint
Public Class iManageFolderView
Inherits System.Web.UI.WebControls.WebParts.WebPart
Implements IWebActionable
Dim _verb As WebPartVerbCollection
'used to build the error message to display to the user
Dim strErrorMsg As New StringBuilder
'property variables
Dim _ctext As String = ""
Dim _bAllowCaching As Boolean = True
Dim _bSortDescending As Boolean = False
Dim _DataCache As String = ""
Private ds As New DataSet
Private myTitle As String
Private reftome As String
#Region " Properties"
<WebBrowsable(False), Personalizable(True), WebDisplayName("iManage Folder ID"), Category("Miscellaneous"), DefaultValue(""), WebDescription("iManage Folder ID")> _
Property [cText]() As String
Get
Return _ctext
End Get
Set(ByVal Value As String)
_ctext = Value
End Set
End Property
<WebBrowsable(False), Personalizable(True), WebDisplayName("Data Cache"), Category("Miscellaneous"), DefaultValue(""), WebDescription("Data Cache")> _
Property [DataCache]() As String
Get
Return _DataCache
End Get
Set(ByVal Value As String)
_DataCache = Value
End Set
End Property
<WebBrowsable(True), Personalizable(True), WebDisplayName("Allow Caching"), Category("Miscellaneous"), DefaultValue(True), WebDescription("Allow Caching")> _
Property [bAllowCaching]() As Boolean
Get
Return _bAllowCaching
End Get
Set(ByVal Value As Boolean)
_bAllowCaching = Value
End Set
End Property
<WebBrowsable(True), Personalizable(True), WebDisplayName("Sort Descending"), Category("Miscellaneous"), DefaultValue(False), WebDescription("Sorts the list in descending order.")> _
Property [bSortDescending]() As Boolean
Get
Return _bSortDescending
End Get
Set(ByVal Value As Boolean)
_bSortDescending = Value
End Set
End Property
#End Region
Public Overrides ReadOnly Property Verbs() As System.Web.UI.WebControls.WebParts.WebPartVerbCollection
Get
Try
If _verb Is Nothing Then
Dim _verbList As New ArrayList
Dim onlyVerb As New WebPartVerb("Refresh", New WebPartEventHandler(AddressOf ClearCache))
onlyVerb.Text = "Refresh Folder Listing"
onlyVerb.Description = "Refreshes folder listing"
onlyVerb.Visible = True
onlyVerb.Enabled = True
_verbList.Add(onlyVerb)
_verb = New WebPartVerbCollection(_verbList)
End If
Catch ex As Exception
Me.strErrorMsg.Append("Error Occured During Verbs()")
Me.strErrorMsg.Append("<br />")
Me.strErrorMsg.Append("Error Message:")
Me.strErrorMsg.Append(ex.Message)
Me.strErrorMsg.Append("<br />")
Me.strErrorMsg.Append("Stack Trace: ")
Me.strErrorMsg.Append(ex.StackTrace)
End Try
Return _verb
End Get
End Property
Protected Sub ClearCache(ByVal sender As System.Object, ByVal e As WebParts.WebPartEventArgs)
Me.DataCache = ""
End Sub
Protected Overrides Sub CreateChildControls()
MyBase.CreateChildControls()
Try
'if we have not entered an imanage folder yet, do not continue
If Me.cText = "" Then
strErrorMsg.Append("Open the Tool Pane and select an Interwoven folder to display.")
Exit Sub
End If
'if we are allowing caching and data has been cached, use it,
'else, get data and populate the cache for next time
If bAllowCaching = True And DataCache <> "" Then
Dim oXMLDoc As New XmlDocument
oXMLDoc.LoadXml(Me.DataCache)
ds.ReadXml(New XmlNodeReader(oXMLDoc))
'debug
Me.strErrorMsg.Append("<br />Showing cached data.")
Else
Me.strErrorMsg.Append("<br />Getting data from iManage.")
Me.reftome = Me.ID
'imanage variables
. . .
Custom code fills the dataset’s table with an XML document here
. . .
ds.Tables.Add(dt)
'if caching is turned on in this webpart, populate the cache for next time.
If bAllowCaching Then
SPSecurity.RunWithElevatedPrivileges(AddressOf ElevatedSaveCache)
End If
End If
. . . display the data from the dataset
Catch ex As Exception
Me.strErrorMsg.Append(ex.Message & ex.StackTrace)
End Try
End Sub
Sub ElevatedSaveCache()
Try
Dim siteColl As SPSite = SPContext.Current.Site
Dim site As SPWeb = SPContext.Current.Web
Using ElevatedsiteColl As SPSite = New SPSite(siteColl.ID)
Using ElevatedSite As SPWeb = ElevatedsiteColl.OpenWeb(site.ID)
ElevatedSite.AllowUnsafeUpdates = True
Dim wpm As SPLimitedWebPartManager = ElevatedSite.GetLimitedWebPartManager(Me.Page.Request.RawUrl, PersonalizationScope.Shared)
Dim wp As iManageFolderView = wpm.WebParts(Me.reftome)
wp.DataCache = Me.ds.GetXml
wp.Title = Me.myTitle
wpm.SaveChanges(wp)
ElevatedSite.AllowUnsafeUpdates = False
End Using
End Using
Catch ex As Exception
Me.strErrorMsg.Append(ex.Message & ex.StackTrace)
End Try
End Sub
Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter)
Try
MyBase.RenderContents(writer)
If strErrorMsg.Length > 0 Then
writer.WriteLine(strErrorMsg.ToString)
End If
Catch ex As Exception
writer.WriteLine(String.Concat("Error Message: ", ex.Message, "<br /> Stack Trace: ", ex.StackTrace))
End Try
End Sub
Public Overrides ReadOnly Property WebBrowsableObject() As Object
Get
Return MyBase.WebBrowsableObject
End Get
End Property
Public Overrides Function CreateEditorParts() As System.Web.UI.WebControls.WebParts.EditorPartCollection
Try
Dim editors As List(Of EditorPart) = New List(Of EditorPart)
Dim part As EditorPart = New FolderViewEditorPart()
part.ID = Me.ID & "_FolderViewEditorPart"
editors.Add(part)
' create the editorpart collection and return it
Dim epc As EditorPartCollection = New EditorPartCollection(editors)
Return epc
Catch ex As Exception
strErrorMsg.Append(ex.Message & ex.StackTrace)
Return MyBase.CreateEditorParts
End Try
End Function
End Class