Common Custom controls
Common_CustomControls_VBNet\CustomControlsWebSite\App_Code\TextFilePersonalizationProvider.vb
' Copyright 2010 ESRI
' 
' All rights reserved under the copyright laws of the United States
' and applicable international laws, treaties, and conventions.
' 
' You may freely redistribute and use this sample code, with or
' without modification, provided you include the original copyright
' notice and use restrictions.
' 
' See the use restrictions.
' 

Imports Microsoft.VisualBasic
Imports System
Imports System.Configuration.Provider
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI.WebControls.WebParts
Imports System.Collections.Specialized
Imports System.Security.Cryptography
Imports System.Text
Imports System.IO

Public Class TextFilePersonalizationProvider
  Inherits PersonalizationProvider
  Public Overrides Property ApplicationName() As String
    Get
      Throw New NotSupportedException()
    End Get
    Set
      Throw New NotSupportedException()
    End Set
  End Property

  Public Overrides Sub Initialize(ByVal name As String, ByVal config As NameValueCollection)
    ' Verify that config isn't null
    If config Is Nothing Then
      Throw New ArgumentNullException("config")
    End If

    ' Assign the provider a default name if it doesn't have one
    If String.IsNullOrEmpty(name) Then
      name = "TextFilePersonalizationProvider"
    End If

    ' Add a default "description" attribute to config if the
    ' attribute doesn't exist or is empty
    If String.IsNullOrEmpty(config("description")) Then
      config.Remove("description")
      config.Add("description", "Text file personalization provider")
    End If

    ' Call the base class's Initialize method
    MyBase.Initialize(name, config)

    ' Throw an exception if unrecognized attributes remain
    If config.Count > 0 Then
      Dim attr As String = config.GetKey(0)
      If (Not String.IsNullOrEmpty(attr)) Then
        Throw New ProviderException ("Unrecognized attribute: " & attr)
      End If
    End If

    ' Make sure we can read and write files in the
    ' ~/App_Data/Personalization_Data directory
    Dim permission As FileIOPermission = New FileIOPermission (FileIOPermissionAccess.AllAccess, HttpContext.Current.Server.MapPath ("~/App_Data/Personalization_Data"))
    permission.Demand()
  End Sub

  Protected Overrides Sub LoadPersonalizationBlobs(ByVal webPartManager As WebPartManager, ByVal path As String, ByVal userName As String, ByRef sharedDataBlob As Byte(), ByRef userDataBlob As Byte())
    ' Load shared state
    Dim reader1 As StreamReader = Nothing
    sharedDataBlob = Nothing

    Try
      reader1 = New StreamReader(GetPath(Nothing, path))
      sharedDataBlob = Convert.FromBase64String(reader1.ReadLine())
    Catch e1 As FileNotFoundException
      ' Not an error if file doesn't exist
    Finally
      If Not reader1 Is Nothing Then
        reader1.Close()
      End If
    End Try

    ' Load private state if userName holds a user name
    If (Not String.IsNullOrEmpty(userName)) Then
      Dim reader2 As StreamReader = Nothing
      userDataBlob = Nothing

      Try
        reader2 = New StreamReader(GetPath(userName, path))
        userDataBlob = Convert.FromBase64String(reader2.ReadLine())
      Catch e2 As FileNotFoundException
        ' Not an error if file doesn't exist
      Finally
        If Not reader2 Is Nothing Then
          reader2.Close()
        End If
      End Try
    End If
  End Sub

  Protected Overrides Sub ResetPersonalizationBlob(ByVal webPartManager As WebPartManager, ByVal path As String, ByVal userName As String)
    ' Delete the specified personalization file
    Try
      File.Delete(GetPath(userName, path))
    Catch e1 As FileNotFoundException
    End Try
  End Sub

  Protected Overrides Sub SavePersonalizationBlob(ByVal webPartManager As WebPartManager, ByVal path As String, ByVal userName As String, ByVal dataBlob As Byte())
    Dim writer As StreamWriter = Nothing

    Try
      writer = New StreamWriter(GetPath(userName, path), False)
      writer.WriteLine(Convert.ToBase64String(dataBlob))
    Finally
      If Not writer Is Nothing Then
        writer.Close()
      End If
    End Try
  End Sub

  Public Overrides Function FindState(ByVal scope As PersonalizationScope, ByVal query As PersonalizationStateQuery, ByVal pageIndex As Integer, ByVal pageSize As Integer, <System.Runtime.InteropServices.Out()> ByRef totalRecords As Integer) As PersonalizationStateInfoCollection
    Throw New NotSupportedException()
  End Function

  Public Overrides Function GetCountOfState(ByVal scope As PersonalizationScope, ByVal query As PersonalizationStateQuery) As Integer
    Throw New NotSupportedException()
  End Function

  Public Overrides Function ResetState(ByVal scope As PersonalizationScope, ByVal paths As String(), ByVal usernames As String()) As Integer
    Throw New NotSupportedException()
  End Function

  Public Overrides Function ResetUserState(ByVal path As String, ByVal userInactiveSinceDate As DateTime) As Integer
    Throw New NotSupportedException()
  End Function

  Private Function GetPath(ByVal userName As String, ByVal path As String) As String
    Dim sha As SHA1CryptoServiceProvider = New SHA1CryptoServiceProvider()
    Dim encoding As UnicodeEncoding = New UnicodeEncoding()
    Dim hash As String = Convert.ToBase64String(sha.ComputeHash (encoding.GetBytes(path))).Replace("/"c, "_"c)

    If String.IsNullOrEmpty(userName) Then
      Return HttpContext.Current.Server.MapPath (String.Format("~/App_Data/Personalization_Data/{0}_Personalization.txt", hash))
    Else
      ' NOTE: Consider validating the user name here to prevent
      ' malicious user names such as "../Foo" from targeting
      ' directories other than ~/App_Data/Personalization_Data

      Return HttpContext.Current.Server.MapPath (String.Format("~/App_Data/Personalization_Data/{0}_{1}_Personalization.txt", userName.Replace("\"c, "_"c), hash))
    End If
  End Function
End Class