2016-04-05 76 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