I have a MustInherit class (AllowDenyPermissionBase) that descends from PermissionBase. I use this as the ancestor for all my simple custom Allow/Deny permission types so that they only require a couple of lines each to define.
The problem is that AllowDenyPermissionBase shows up on the New action menu when editing the Permissions list for a Role.
I have tried (1) applying the CreatableItem(False) attribute to the class, (2) making the DetailView and ListView for the class ReadOnly, and (3) using a regular ObjectAccessPermission to deny AllAccess to the class. No joy.
Is there a way to prevent the New action menu from showing abstract classes?
Thanks…
We have closed this ticket because another page addresses its subject:
Security.Permissions - Abstract permission classes are displayed in the New Action's Items list
Hi David,
Sorry for the delay in responding. To accomplish this, add a new view controller to the application module of your solution:
using System; using DevExpress.ExpressApp; using DevExpress.ExpressApp.SystemModule; namespace MainDemo.Module { public partial class ViewController1 : ViewController { public ViewController1() { InitializeComponent(); RegisterActions(components); TargetViewId = "RoleBase_PersistentPermissions_ListView"; } protected override void OnActivated() { base.OnActivated(); Frame.GetController<NewObjectViewController>().CollectDescendants += new EventHandler<CollectTypesEventArgs>(ViewController1_CollectDescendants); } void ViewController1_CollectDescendants(object sender, CollectTypesEventArgs e) { foreach (Type item in e.Types) { if (item == typeof(MyPermissionBase)) { e.Types.Remove(item); return; } } } } }
In addition, I suggest you refer to the following help topic: Reuse Controllers and Actions. It may be helpful as well.
Thanks,
Dennis
Thanks for the quick response. I'm trying this solution but still having some difficulty. The code I am using (in VB) is below.
The event handler executes when expected, but when it gets to the For Each loop, e.Types contains only one item, which is the type PersistentPermission. So there is no AllowDenyPermission type (my abstract type) to be removed and nothing happens.
Have I made a mistake in translating the code from C#??? (It wouldn't be the first time…)
Public Sub New()
MyBase.New()
'This call is required by the Component Designer.
InitializeComponent()
RegisterActions(components)
TargetViewId = "RoleBase_PersistentPermissions_ListView"
End Sub
Protected Overrides Sub OnActivated()
MyBase.OnActivated()
AddHandler Frame.GetController(Of NewObjectViewController)().CollectDescendants, _
AddressOf CollectDescendantsHandler
End Sub
Private Sub CollectDescendantsHandler(ByVal sender As Object, ByVal e As CollectTypesEventArgs)
'// At this point e.Types has only one item, type PersistentPermission,
'// so there is nothing to remove.
For Each item As Type In e.Types
If item Is GetType(AllowDenyPermission) Then
e.Types.Remove(item)
Exit For
End If
Next
End Sub
The following code seems to do the trick, but I'm not sure it's the right way to go. I'm pretty sure that the NewObjectAction.Items collection is the one I should be acting on, but perhaps I should be reacting to a different event. It seems odd to run through the collection every time it is changed, but that's the only event I can find that let's me get to this collection after it is filled.
Any suggestions???
Protected Overrides Sub OnActivated()
MyBase.OnActivated()
Dim newObjController = Frame.GetController(Of NewObjectViewController)()
Dim newObjAction = newObjController.NewObjectAction
AddHandler newObjAction.ItemsChanged, AddressOf RemoveTypeFromChoiceList
End Sub
Private Sub RemoveTypeFromChoiceList(ByVal sender As Object, ByVal e As EventArgs)
Dim newObjAction = DirectCast(sender, SingleChoiceAction)
For Each item In newObjAction.Items
If item.Data Is GetType(AllowDenyPermission) Then
newObjAction.Items.Remove(item)
Exit For
End If
Next
End Sub
Hi David,
Thank you for the update.
Your last solution is also correct and you can use it.
I have converted my code in VB.Net and it will look like this in the 8.2 version of the suite:
Partial Public Class ViewController1 Inherits ViewController Public Sub New() TargetViewId = "RoleBase_PersistentPermissions_ListView" End Sub Protected Overrides Sub OnActivated() MyBase.OnActivated() AddHandler Frame.GetController(Of NewObjectViewController)().CollectDescendantTypes, AddressOf ViewController1_CollectDescendantTypes End Sub Private Sub ViewController1_CollectDescendantTypes(ByVal sender As Object, ByVal e As CollectTypesEventArgs) For Each item As Type In e.Types If item Is GetType(MyPermissionBase) Then e.Types.Remove(item) Return End If Next item End Sub End Class Public MustInherit Class MyPermissionBase Inherits PermissionBase Protected Friend Sub New() End Sub End Class Public Class MyClass1 Inherits MyPermissionBase Public Overrides Function Copy() As System.Security.IPermission Return New MyClass1() End Function End Class Public Class MyClass2 Inherits MyPermissionBase Public Overrides Function Copy() As System.Security.IPermission Return New MyClass2() End Function End Class End Class
It all works fine for me. Could you please upgrade to the latest version of XAF?
I have also created a new bug report with ID B31829 (Security.Permissions - Abstract permission classes are displayed in the New Action's Items list) advising against using such controllers as a workaround.
Thanks,
Dennis
I think I see part of the problem.
Your original C# code attached a handler to Frame.GetController<NewObjectViewController>().CollectDescendants.
Your new VB code attaches the handler to Frame.GetController(Of NewObjectViewController)().CollectDescendantTypes instead.
In 8.1.6, event CollectDescendantTypes doesn't exist, but event CollectDescendants does. Maybe these function a little differently.
So I'm assuming that this code works only in 8.2. I'll just have to wait as I can't really work with that until it gets out of beta.
Thanks…
Hi David,
I suggest you use your own work around since it is more effective than mine. I have attached a complete and refactored version of my sample project which works fine for me for both CS and VB projects under the 8.1.6 version of the suite:
Imports Microsoft.VisualBasic Imports System Imports DevExpress.ExpressApp Imports DevExpress.ExpressApp.SystemModule Imports DevExpress.ExpressApp.Security Imports DevExpress.ExpressApp.Actions Namespace WinSolution.Module.Win Partial Public Class ViewController1 Inherits ViewController Public Sub New() InitializeComponent() RegisterActions(components) TargetViewId = "RoleBase_PersistentPermissions_ListView" End Sub Protected Overrides Sub OnActivated() MyBase.OnActivated() AddHandler View.ControlsCreated, AddressOf View_ControlsCreated End Sub Private Sub View_ControlsCreated(ByVal sender As Object, ByVal e As EventArgs) Dim action As SingleChoiceAction = Frame.GetController(Of NewObjectViewController)().NewObjectAction action.BeginUpdate() action.Items.Remove(action.Items.Find(GetType(MyPermissionBase))) action.EndUpdate() End Sub End Class End Namespace
Please let me know in case of any difficulty.
Thanks,
Dennis