Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 确定AuthorizeAttribute是在类级别还是在方法级别_Asp.net Mvc_Vb.net - Fatal编程技术网

Asp.net mvc 确定AuthorizeAttribute是在类级别还是在方法级别

Asp.net mvc 确定AuthorizeAttribute是在类级别还是在方法级别,asp.net-mvc,vb.net,Asp.net Mvc,Vb.net,我正在创建一个自定义AuthorizeAttribute,我想在自定义AuthorizeAttribute的New()方法中检查当前属性是在类(控制器)级别还是在方法(操作)级别声明的 我的控制器: <CustomAuthorization> Public Class SeomController ... <CustomAuthorization> Function Index() As ActionResult 这不是你问题的答案,但可能是另一种选择

我正在创建一个自定义AuthorizeAttribute,我想在自定义AuthorizeAttribute的New()方法中检查当前属性是在类(控制器)级别还是在方法(操作)级别声明的

我的控制器:

<CustomAuthorization>
Public Class SeomController
...
    <CustomAuthorization>
    Function Index() As ActionResult

这不是你问题的答案,但可能是另一种选择

向自定义属性类添加属性

Public Enum Levels
    Controller
    Action
End Enum

Public Class CustomAttributes
    Public Class CustomAuthorize
        Inherits System.Web.Mvc.AuthorizeAttribute
        Private _level As Levels
        Public Property Level() As Levels
            Get
                Return _level
            End Get
            Set(ByVal value As Levels)
                _level = value
            End Set
        End Property
        Protected Overrides Function AuthorizeCore(httpContext As HttpContextBase) As Boolean
            If (_level = Levels.Controller) Then
                'Controller Level
            End If
            Return MyBase.AuthorizeCore(httpContext)
        End Function
    End Class
End Class
然后,您可以在添加属性时仅指示该属性的指定位置

<CustomAttributes.CustomAuthorize(Level:=Levels.Controller)>
Public Class AccountController

    <CustomAttributes.CustomAuthorize(Level:=Levels.Action)>
    Public Function Login(returnUrl As String) As ActionResult
        ViewBag.ReturnUrl = returnUrl
        Return View()
    End Function

公共类帐户控制器
作为ActionResult的公共函数登录(返回URL作为字符串)
ViewBag.ReturnUrl=ReturnUrl
返回视图()
端函数
属性,因此不建议创建自我感知属性

但是如果您采用链接文章中的方法,您可以创建一个全局
IAuthorizationFilter
,以确定属性的注册位置

CustomAuthorizationAttribute 首先,您需要一个“dumb”authorize属性,它只是一个属性(而不是
AuthorizeAttribute
子类),用于标记控制器和操作。它足够聪明,可以收集元数据并将其拆分为数组以便于访问,但仅此而已

<AttributeUsage(AttributeTargets.[Class] Or AttributeTargets.Method, Inherited := True)> _
Public Class CustomAuthorizationAttribute
    Inherits Attribute
    Private m_users As String
    Private m_usersSplit As String()
    Private m_roles As String
    Private m_rolesSplit As String()

    Public Property Users() As String
        Get
            Return Me.m_users
        End Get
        Set
            Me.m_users = value
            Me.m_usersSplit = SplitString(value)
        End Set
    End Property

    Public Property Roles() As String
        Get
            Return Me.m_roles
        End Get
        Set
            Me.m_roles = value
            Me.m_rolesSplit = SplitString(value)
        End Set
    End Property

    Friend ReadOnly Property UsersSplit() As String()
        Get
            Return Me.m_usersSplit
        End Get
    End Property

    Friend ReadOnly Property RolesSplit() As String()
        Get
            Return Me.m_rolesSplit
        End Get
    End Property

    Friend Shared Function SplitString(original As String) As String()
        If String.IsNullOrEmpty(original) Then
            Return New String(-1) {}
        End If
        Return (From piece In original.Split(New Char() {","C})Let trimmed = piece.Trim() Where Not String.IsNullOrEmpty(trimmed)trimmed).ToArray(Of String)()
    End Function
End Class
用法 全局注册您的
CustomAuthorizationFilter
,以便它可以检测您的属性所在位置(并运行任何其他授权逻辑)

然后正常装饰你的控制器和动作

<CustomAuthorization>
Public Class SeomController
...
    <CustomAuthorization>
    Function Index() As ActionResult

公共类SeomController
...
函数Index()作为ActionResult

您可以添加一个参数并使用它<代码>自定义授权(Level=Levels.Class)]是的,如果我没有找到不需要在控制器/操作级别上添加任何额外内容的解决方案,我正计划这样做哇!对谢谢你,谢谢你花时间用VB写下这一切!欢迎光临。虽然我不是用VB写的,而是用C#写的,然后用了一个转换器:)。我认为它转换正确,但是如果它的任何部分没有编译,请告诉我。是的,我认为CustomAuthorizationFilter中的
CustomAuthorization
显示的是CustomAuthorizationAttribute,修剪的部分没有编译,尽管我看到了您在那里尝试的操作。。。
Public Class CustomAuthorizationFilter
    Inherits AuthorizeAttribute
    Private Enum Level
        Action
        Controller
    End Enum

    Private Function GetCustomAuthorizationAttribute(actionDescriptor As ActionDescriptor, ByRef registeredLevel As Level) As CustomAuthorizationAttribute
        Dim result As CustomAuthorizationAttribute = Nothing

        ' Check if the attribute exists on the action method
        result = DirectCast(actionDescriptor.GetCustomAttributes(attributeType := GetType(CustomAuthorizationAttribute), inherit := True).SingleOrDefault(), CustomAuthorizationAttribute)

        If result IsNot Nothing Then
            registeredLevel = Level.Action
            Return result
        End If

        ' Check if the attribute exists on the controller
        result = DirectCast(actionDescriptor.ControllerDescriptor.GetCustomAttributes(attributeType := GetType(CustomAuthorizationAttribute), inherit := True).SingleOrDefault(), CustomAuthorizationAttribute)

        registeredLevel = Level.Controller
        Return result
    End Function

    Protected Overrides Function AuthorizeCore(httpContext As HttpContextBase) As Boolean
        Dim actionDescriptor = TryCast(httpContext.Items("ActionDescriptor"), ActionDescriptor)
        If actionDescriptor IsNot Nothing Then
            Dim registeredLevel As Level
            Dim authorizeAttribute = Me.GetCustomAuthorizationAttribute(actionDescriptor, registeredLevel)

            ' If the authorization attribute exists
            If authorizeAttribute IsNot Nothing Then
                If registeredLevel = Level.Action Then
                        ' Attribute is registered on an action
                        ' Implement user and role checking logic using
                        '
                        ' authorizeAttribute.RolesSplit
                        ' authorizeAttribute.UsersSplit
                ElseIf registeredLevel = Level.Controller Then
                        ' Attribute is registered on a controller
                        ' Implement user and role checking logic using
                        '
                        ' authorizeAttribute.RolesSplit
                        ' authorizeAttribute.UsersSplit
                End If
            End If
        End If

        Return True
    End Function

    Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext)
        ' Pass the current action descriptor to the AuthorizeCore
        ' method on the same thread by using HttpContext.Items
        filterContext.HttpContext.Items("ActionDescriptor") = filterContext.ActionDescriptor
        MyBase.OnAuthorization(filterContext)
    End Sub
End Class
Public Class FilterConfig
    Public Shared Sub RegisterGlobalFilters(ByVal filters As GlobalFilterCollection)
        filters.Add(New CustomAuthorizationFilter())
        filters.Add(New HandleErrorAttribute())
    End Sub
End Class
<CustomAuthorization>
Public Class SeomController
...
    <CustomAuthorization>
    Function Index() As ActionResult