开发者

Connect reusable ASP.NET WebControl to a method for loading data

I'm trying to create a control that can extend other webcontrols and set some properties like visible and enabled, based on user permissions.

Here's an example where your user role would need to include the "CanSave" permission:

<asp:Button ID="btn1" runat="server" Text="Save"/>
<myControls:PermissionsExtender runat="server" ControlToSet="btn1" Permission="CanSave"/>

I'm trying to keep this reusable, that's why the PermissionExtender is in a separate project that can not have any dependencies to other projects. To make a decision, the control of course needs to get this info from somewhere else (database or something). I made another control and, using events, the above extender will be set by a master control, so only that needs to know where to look up the information.

The master control now needs to be configured to know where the information about roles and permissions will be coming from. My idea was to have an interface inside the reusable project, and implement that somewhere else, then configure my control to go and find the cl开发者_开发问答ass that implements the method I need and load it through reflection. But I'm unclear how this could work. I would probably place the master control in the masterpage and supply it a class name like PermissionClass="SecurityLibrary.PermissionsClass". Kinda like ObjectDatasource does it, but other suggestions are welcome.

The method signature would be like: bool HasPermission(string permission) It would know the current users role and using that combination, looks up if the role includes the permission.

How can I wire up a call from the control to a method inside my main project that can supply the necessary information without making them dependent.


I think I've got something that will work for you (tested fine for me but I may have misunderstood part of what you were looking for). With this implementation the asp.net designer code will look like this:

    <web:PermissionMasterControl runat="server" ID="masterController" PermissionClass="SecurityLibrary.RandomPermissionClass" />

    <asp:Button ID="btnSave" runat="server" Text="save" />
    <web:PermissionExtender runat="server" ControlToSet="btnSave" Permission="CanSave" MasterControllerID="masterController" />

Now for the SecurityLibrary. Pretty straight forward, I included a simple "RandomPermissionClass" that randomly returns true/false.

Namespace SecurityLibrary
    Public MustInherit Class PermissionClass
        Public MustOverride Function HasPermission(ByVal permission As String) As Boolean
    End Class

    Public Class RandomPermissionClass
        Inherits PermissionClass

        Private rand As New Random()

        Public Overrides Function HasPermission(permission As String) As Boolean
            Return If(rand.Next(2) = 0, False, True)
        End Function
    End Class
End Namespace

Now we have the "myControls" library, which contains no references to SecurityLibrary. I created two controls and a delegate. The controls are "PermissionMasterControl" and "PermissionExtender". The delegate is what is used to actually perform the check against the reflected object.

Namespace myControls
    Public Delegate Function HasPermissionDelegate(ByVal permission As String) As Boolean

    Public Class PermissionMasterControl
        Inherits System.Web.UI.Control

        Public Property PermissionClass As String
            Get
                Return If(ViewState("PermissionClass") Is Nothing, "", ViewState("PermissionClass").ToString())
            End Get
            Set(value As String)
                ViewState("PermissionClass") = value
            End Set
        End Property

        Private ReadOnly Property PermissionDelegate As HasPermissionDelegate
            Get
                If _permissionDel Is Nothing Then
                    If Not String.IsNullOrEmpty(PermissionClass) Then
                        Dim t = Type.GetType(PermissionClass, False)

                        If t IsNot Nothing Then
                            _permissionObj = Activator.CreateInstance(t)

                            Dim mi As MethodInfo = _
                                    t.GetMethod("HasPermission", BindingFlags.Public Or BindingFlags.Instance)

                            _permissionDel = [Delegate].CreateDelegate(GetType(HasPermissionDelegate), _permissionObj, mi)

                        End If
                    End If
                End If

                Return _permissionDel
            End Get
        End Property

        Private _permissionObj As Object = Nothing
        Private _permissionDel As HasPermissionDelegate = Nothing

        Public Function HasPermission(ByVal permission As String) As Boolean
            If PermissionDelegate Is Nothing Then
                Throw New NullReferenceException("The specified permission class (" + PermissionClass + ") could not be loaded/found.")
            End If

            Return PermissionDelegate(permission)
        End Function
    End Class

    Public Class PermissionExtender
        Inherits System.Web.UI.Control

        Public Property ControlToSet As String
            Get
                Return If(ViewState("ControlToSet") Is Nothing, "", ViewState("ControlToSet").ToString())
            End Get
            Set(value As String)
                ViewState("ControlToSet") = value
            End Set
        End Property

        Public Property Permission As String
            Get
                Return If(ViewState("Permission") Is Nothing, "", ViewState("Permission").ToString())
            End Get
            Set(value As String)
                ViewState("Permission") = value
            End Set
        End Property

        Public Property MasterControllerID As String
            Get
                Return If(ViewState("MasterControllerID") Is Nothing, "", ViewState("MasterControllerID").ToString())
            End Get
            Set(value As String)
                ViewState("MasterControllerID") = value
            End Set
        End Property

        Protected ReadOnly Property MasterController As PermissionMasterControl
            Get
                If _mastercontroller Is Nothing Then
                    _mastercontroller = Me.Page.FindControl(MasterControllerID)
                End If

                Return _mastercontroller
            End Get
        End Property

        Protected ReadOnly Property ManagedControl As Control
            Get
                If _controlToSet Is Nothing Then
                    _controlToSet = Me.NamingContainer.FindControl(ControlToSet)
                End If

                Return _controlToSet
            End Get
        End Property

        Private _controlToSet As Control = Nothing
        Private _mastercontroller As PermissionMasterControl = Nothing


        Protected Overrides Sub OnLoad(e As System.EventArgs)
            MyBase.OnLoad(e)

            Dim bResult As Boolean = MasterController.HasPermission(Permission)

            ManagedControl.Visible = bResult
        End Sub
    End Class
End Namespace
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜