2016-04-05 7 views
0

J'ai attribut personnalisé appliqué à des méthodes CRUD référentiel pour contrôler l'accès:CodeAccessSecurityAttribute lancer classe dérivée System.TypeLoadException (panne est survenue lors du chargement d'un type)

Public Class SecureDbContextGenericRepository(Of TEntity As Class, TContext As DbContext) 
    Inherits DbContextGenericRepository(Of TEntity, TContext) 
    Public Sub New(connectionService As IConnectionService) 
    MyBase.New(connectionService) 
    End Sub 
    <EmployeeRoleRequirement(SecurityAction.Demand, EmployeeRoles:=EmployeeRoles.DataWriter)> 
    Public Overrides Sub Delete(ParamArray entities() As TEntity) 
    MyBase.Delete(entities) 
    End Sub 
    <EmployeeRoleRequirement(SecurityAction.Demand, EmployeeRoles:=EmployeeRoles.DataWriter)> 
    Public Overrides Sub Insert(ParamArray entities() As TEntity) 
    MyBase.Insert(entities) 
    End Sub 
    <EmployeeRoleRequirement(SecurityAction.Demand, EmployeeRoles:=EmployeeRoles.DataReader)> 
    Public Overrides Function [Select](Optional predicate As Func(Of TEntity, Boolean) = Nothing) As IList(Of TEntity) 
    Return MyBase.Select(predicate) 
    End Function 
    <EmployeeRoleRequirement(SecurityAction.Demand, EmployeeRoles:=EmployeeRoles.DataWriter)> 
    Public Overrides Sub Update(ParamArray entities() As TEntity) 
    MyBase.Update(entities) 
    End Sub 
End Class 

Ceci est la mise en œuvre de l'attribut:

Public Class EmployeeRoleRequirementAttribute 
    Inherits CodeAccessSecurityAttribute 
    Public Sub New(action As SecurityAction) 
     MyBase.New(action) 
    End Sub 

    Public Overrides Function CreatePermission() As IPermission 
     Return New EmployeeRolePermission(_EmployeeRoles) 
    End Function 

    Public Property EmployeeRoles As EmployeeRoles 
    End Class 

<Flags> 
    Public Enum EmployeeRoles As Integer 
    DataReader = 0 
    DataWriter = 1 
    End Enum 

Et la permission:

Public Class EmployeeRolePermission 
    Implements IPermission 
    Public Sub New(employeeRoles As EmployeeRoles) 
     _EmployeeRoles = employeeRoles 
    End Sub 

    Public Function Copy() As IPermission Implements IPermission.Copy 
     Return New EmployeeRolePermission(_EmployeeRoles) 
    End Function 
    Public Sub Demand() Implements IPermission.Demand 
     Dim principal = DirectCast(Thread.CurrentPrincipal, ProductionAssistantPrincipal) 
     If Not principal.IsInRole(_EmployeeRoles) Then 
     Throw New SecurityException(String.Format(My.Resources.EmployeeRoleNotFound, 
                principal.Identity.Name, 
                _EmployeeRoles.ToString())) 
     End If 
    End Sub 
    Public Sub FromXml(e As SecurityElement) Implements ISecurityEncodable.FromXml 
     Throw New NotImplementedException() 
    End Sub 
    Public Function Intersect(target As IPermission) As IPermission Implements IPermission.Intersect 
     Return New EmployeeRolePermission(_EmployeeRoles And DirectCast(target, EmployeeRolePermission).EmployeeRoles) 
    End Function 
    Public Function IsSubsetOf(target As IPermission) As Boolean Implements IPermission.IsSubsetOf 
     Return _EmployeeRoles.HasFlag(DirectCast(target, EmployeeRolePermission).EmployeeRoles) 
    End Function 
    Public Function ToXml() As SecurityElement Implements ISecurityEncodable.ToXml 
     Throw New NotImplementedException() 
    End Function 
    Public Function Union(target As IPermission) As IPermission Implements IPermission.Union 
     Return New EmployeeRolePermission(_EmployeeRoles Or DirectCast(target, EmployeeRolePermission).EmployeeRoles) 
    End Function 

    Public ReadOnly Property EmployeeRoles As EmployeeRoles 
    End Class 

Chaque fois que l'un des les méthodes CRUD sont atteintes, TypeLoadException est levée. Je ne sais vraiment pas cause de cela, mais si je supprime des attributs de méthodes CRUD, tout fonctionne bien.

Répondre

1

Cela semble être dû à la propriété enum sur l'attribut (voir https://connect.microsoft.com/VisualStudio/feedback/details/596251/custom-cas-attributes-with-an-enum-property-set-cause-a-typeloadexception pour plus de détails). Pour contourner ce problème, vous pouvez utiliser une propriété de type chaîne sur l'attribut et la convertir en une énumération dans l'éditeur de propriétés ou juste avant de créer l'autorisation. (Personnellement, j'opterais probablement pour le premier dans le but d'activer la validation anticipée, mais ymmv ...)

+0

équipe de développement Visual Studio est tas de débiles réels. Le problème des 6 ans n'est toujours pas résolu. –

0

Une autre solution consiste à créer une propriété d'attribut de type, qui est utilisée dans Enum, dans ce cas Integer.

Public Class EmployeeRoleRequirementAttribute 
    Inherits CodeAccessSecurityAttribute 
    Public Sub New(action As SecurityAction) 
    MyBase.New(action) 
    End Sub 
    Public Overrides Function CreatePermission() As IPermission 
    Return New EmployeeRolePermission(CType(_RequiredEmployeeRoles, EmployeeRoles)) 
    End Function 

    Public Property RequiredEmployeeRoles As Integer 
End Class 

<Flags> 
Public Enum EmployeeRoles As Integer 
    DataReader = 0 
    DataWriter = 1 
End Enum 

Ensuite, vous ne devez utiliser la chaîne, ce qui ne permet pas de combiner facilement des drapeaux quand attribut est utilisé:

<EmployeeRoleRequirement(SecurityAction.Demand, RequiredEmployeeRoles:=EmployeeRoles.DataReader Or EmployeeRoles.DataWriter)> 
Sub SecuredMethod() 
End Sub