将可重用的 ASP.NET WebControl 连接到加载数据的方法
Posted
技术标签:
【中文标题】将可重用的 ASP.NET WebControl 连接到加载数据的方法【英文标题】:Connect reusable ASP.NET WebControl to a method for loading data 【发布时间】:2011-06-22 08:45:23 【问题描述】:我正在尝试创建一个控件,该控件可以扩展其他 web 控件并根据用户权限设置一些属性,例如可见和启用。
这是一个示例,您的用户角色需要包含“CanSave”权限:
<asp:Button ID="btn1" runat="server" Text="Save"/>
<myControls:PermissionsExtender runat="server" ControlToSet="btn1" Permission="CanSave"/>
我试图保持这个可重用,这就是为什么 PermissionExtender 位于一个单独的项目中,不能与其他项目有任何依赖关系。为了做出决定,控制当然需要从其他地方(数据库或其他东西)获取此信息。我制作了另一个控件,并且使用事件,上述扩展器将由主控件设置,因此只需要知道在哪里查找信息。
现在需要对主控件进行配置,以了解有关角色和权限的信息的来源。我的想法是在可重用项目中有一个接口,并在其他地方实现它,然后配置我的控件去找到实现我需要的方法的类并通过反射加载它。但我不清楚这是如何工作的。我可能会将主控件放在母版页中,并为其提供一个类名,如 PermissionClass="SecurityLibrary.PermissionsClass"。有点像 ObjectDatasource 这样做,但欢迎提出其他建议。
方法签名如下:
bool HasPermission(string permission)
它会知道当前用户的角色并使用该组合,查找角色是否包含权限。
如何将控件的调用连接到我的主项目中的一个方法,该方法可以提供必要的信息而不使它们相互依赖。
【问题讨论】:
【参考方案1】:我想我有一些对你有用的东西(测试对我来说很好,但我可能误解了你正在寻找的部分内容)。使用此实现,asp.net 设计器代码将如下所示:
<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" />
现在是 SecurityLibrary。很简单,我包含了一个简单的“RandomPermissionClass”,它随机返回真/假。
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
现在我们有了“myControls”库,其中不包含对 SecurityLibrary 的引用。我创建了两个控件和一个委托。控件是“PermissionMasterControl”和“PermissionExtender”。委托用于实际执行对反射对象的检查。
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
【讨论】:
感谢您为我指明了正确的方向,我现在有一个与您的示例非常相似的解决方案。我使用事件将 MasterController 连接到页面上的多个控件。感觉完整时,我会在这里发布我的解决方案以上是关于将可重用的 ASP.NET WebControl 连接到加载数据的方法的主要内容,如果未能解决你的问题,请参考以下文章