[Web] Menù dinamici basati sui ruoli

1) Definisco la struttura e relative classi per la gestione della configurazione del menù

Imports System.Configuration
Imports System.Xml
Imports System.Xml.Serialization

#Region "MenuItem"
Public Class MenuItem

    < XmlAttributeAttribute() > _
    Public text As String
 
    < XmlAttributeAttribute()> _
    Public navigationUrl As String = String.Empty
    
    < XmlElement("role", IsNullable:=False) > _
    Public roles As String()

    < XmlElement("menuItem", IsNullable:=False) > _
    Public menuItems As MenuItem()

End Class
#End Region

#Region "Menu Configuration Section Handler"
Public Class MenuSectionHandler
    Implements IConfigurationSectionHandler
    Public Function Create(ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) _ 
        As Object Implements System.Configuration.IConfigurationSectionHandler.Create
        
        Dim ser As New XmlSerializer(GetType(MenuItem), New XmlRootAttribute(section.Name))
        Dim r As New XmlNodeReader(section)
        Return ser.Deserialize(r)

    End Function
End Class
#End Region

2) Aggiungo al progetto un nuovo user control (ascx) al quale aggiungo una Table, controllo server-side, che chiamo "mMenuTable". Nel parte di code behind del controllo implemento quanto segue.

Imports System.Configuration
Imports System.Web.Caching
Public Class Menu
    Inherits System.Web.UI.UserControl
    
    #Region " Web Form Designer Generated Code "
    'This call is required by the Web Form Designer.
     Private Sub InitializeComponent()
    End Sub
    Protected WithEvents mMenuTable As System.Web.UI.WebControls.Table
    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object
    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub
    #End Region
    
    Private ReadOnly Property MenuSchema() As MenuItem
        Get
            If (Cache.Item("MENU") Is Nothing) Then
                Dim vMenuSchema As MenuItem = DirectCast(ConfigurationSettings.GetConfig("menuSection"), MenuItem)
                Dim filename As String = MapPath("~/Web.config")
                Cache.Insert("MENU", vMenuSchema, New CacheDependency(filename))
                Return vMenuSchema
            Else
                Return DirectCast(Cache.Item("MENU"), MenuItem)
            End If
        End Get
    End Property
    
    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim depth As Integer
        AddMenuItem(MenuSchema, depth)
    End Sub
    
    Private Sub AddMenuItem(ByVal menuItem As MenuItem, ByRef depth As Integer)
        Try
            depth = depth + 1
 
            'il flag indicherà se l'utente è in uno dei ruoli associati al menù
            Dim userIsInRole As Boolean = True
     
            'controllo se l'utente è in uno dei ruoli associati al menù, se non vi sono ruoli 
            'associati al menù significa che valgono quelli del menù padre     
            Dim role As String
            If (Not menuItem.roles Is Nothing) Then
                For Each role In menuItem.roles
                    If (Page.User.IsInRole(role)) Then
                        userIsInRole = True
                        Exit For
                    End If
                Next
            End If
 
            'se l'utente non ha alcun ruolo associato di quelli richiesti 
            'esco e salto menu e relativa gerarchia 
           If (Not userIsInRole) Then Exit Sub

            'aggiungo menu e ciclo sui sotto menu
            AppendMenuItem(menuItem.text, menuItem.navigationUrl, depth)
            Dim vMenuItem As MenuItem
            If (Not menuItem.menuItems Is Nothing) Then
                For Each vMenuItem In menuItem.menuItems
                    AddMenuItem(vMenuItem, depth)
                Next
            End If
        Finally
            depth = depth - 1
        End Try
    End Sub

    Private Sub AppendMenuItem(ByVal text As String, ByVal navigationUrl As String, ByVal depth As Integer)

        Dim menuItem As Control
        Dim menuText As String = String.Format("{0} {1}", New String("."c, depth - 1), text)

        'se viene specifico un navigationurl è un hyperlink else una label
        If (navigationUrl = String.Empty) Then
            'costruisco label
            Dim menuLabel As New Label
            menuLabel.Text = menuText
            menuItem = menuLabel
        Else
            'costruisco hyperlink per voce menu
            Dim menuLink As New HyperLink
            menuLink.Text = menuText
            menuLink.NavigateUrl = navigationUrl
            menuItem = menuLink
        End If

        'costruisco cella dove posizionare hyperlink
        Dim tdMenuItem As New TableCell
        tdMenuItem.Controls.Add(menuItem)
        'costruisco riga dove posizionare cella
        Dim trMenuItem As New TableRow
        trMenuItem.Cells.Add(tdMenuItem)
        'aggiungo riga a tabella
        mMenuTable.Rows.Add(trMenuItem)
    End Sub
End Class

3) Aggiungo le parte di configurazione nel web.config dell'applicazione

< configSections >
    < section name="menuSection" type="NorthWindVBNET.MenuSectionHandler, NorthWindVBNET" / >
< / configSections >
< menuSection text="Menu" >
    < role >user< / role >
 < menuItem text="Home" navigationUrl="~/Home.aspx"/>
 < menuItem text="BackOffice">
    < role >admin< / role> 
    < menuItem navigationUrl="~/BackOffice/EmployeesList.aspx" text="Employees List"  />    
 < / menuItem >
 < menuItem text="Services">
    < menuItem navigationUrl="~/Services/LogOut.aspx" text="Log Out"/ >
 < / menuItem >
< / menuSection >

4) Aggiungo/trascino lo user control (che io ho chiamato Menu.ascx) nelle pagine che vogliamo abbiamo il menù.

posted @ lunedì 9 maggio 2005 13:38

Print
Comments have been closed on this topic.
«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011