【问题标题】:CodeAccessSecurityAttribute derived class throwing System.TypeLoadException (Failure has occurred while loading a type)CodeAccessSecurityAttribute 派生类抛出 System.TypeLoadException(加载类型时发生故障)
【发布时间】:2016-04-05 13:56:43
【问题描述】:

我已将自定义属性应用于 CRUD 存储库方法以控制访问:

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 方法中删除属性,一切正常。

【问题讨论】:

    标签: vb.net permissions code-access-security


    【解决方案1】:

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

    【讨论】:

    • Visual Studio 开发团队是一群真正的智障。 6 年前的问题仍未解决。
    【解决方案2】:

    另一种解决方法是制作类型的属性属性,它在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多