2016-04-05 33 views
0

我已经自定义属性应用到CRUD库的方法来控制访问:CodeAccessSecurityAttribute派生类投掷System.TypeLoadException(在加载类型已发生故障)

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 

这是实现属性:

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 

和权限:

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 

每次之一CRUD方法已经到达,抛出了TypeLoadException。我真的不知道这个原因,但如果我从CRUD方法中删除属性,一切正常。

回答

1

这似乎是由于属性上的枚举值属性(有关详细信息,请参阅https://connect.microsoft.com/VisualStudio/feedback/details/596251/custom-cas-attributes-with-an-enum-property-set-cause-a-typeloadexception)。要解决此问题,可以在属性上使用字符串值属性,并在属性设置器中或在创建权限之前将其强制转换为枚举。 (就我个人而言,我可能会选择前者来实现早期验证,但是ymmv ...)

+0

Visual Studio开发团队是一群真正的延缓的。 6岁的问题仍然没有解决。 –

0

另一个解决方法是制作用于Enum中的属性属性,在此情况下为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 

然后你不需要用String,不允许容易标志组合使用时,属性:

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