如何获取 dotnet core 3 的路由属性?

我已将 dotnet core 2.2 升级到 3.preview 7。

因此之后,我无法获取自定义属性。

context.Resource在版本 2.2 中是类型 of AuthorizationFilterContext,但在版本 3 中是类型 of Microsoft.AspNetCore.Http.Endpoint。


现在我无法从端点获取属性。


using Microsoft.AspNetCore.Authorization;

using Microsoft.AspNetCore.Mvc.Controllers;

using Microsoft.AspNetCore.Mvc.Filters;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Threading.Tasks;


namespace Gamma.Core.Security

{

    public abstract class AttributeAuthorizationHandler<TRequirement,     TAttribute>

    : AuthorizationHandler<TRequirement> where TRequirement

    : IAuthorizationRequirement where TAttribute : Attribute

    {

        Microsoft.AspNetCore.Http.IHttpContextAccessor _httpContextAccessor = null;

        public AttributeAuthorizationHandler(Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor)

        {

            _httpContextAccessor = httpContextAccessor;

        }

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement)

        {

            var attributes = new List<TAttribute>();


            var action = (context.Resource as AuthorizationFilterContext)?.ActionDescriptor as ControllerActionDescriptor;

            if (context.Resource is Microsoft.AspNetCore.Http.Endpoint endpoint)

            {

                //endpoint.

            }


            if (action != null)

            {

                attributes.AddRange(GetAttributes(action.MethodInfo));

            }


            return HandleRequirementAsync(context, requirement, attributes);

        }


        protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement, IEnumerable<TAttribute> attributes);


        private static IEnumerable<TAttribute> GetAttributes(MemberInfo memberInfo)

        {

            return memberInfo.GetCustomAttributes(typeof(TAttribute), false).Cast<TAttribute>();

        }

    }

}


沧海一幻觉
浏览 220回答 4
4回答

狐的传说

我能够通过在AuthorizationHandlerContext中使用来获取 .NET Core 3.1 中的自定义属性。ControllerActionDescriptorprivate IEnumerable<TAttribute> GetAttributes<TAttribute>(AuthorizationHandlerContext authContext){    if (authContext.Resource is RouteEndpoint routeEndpoint)    {        var actionDescriptor = routeEndpoint.Metadata.OfType<ControllerActionDescriptor>().SingleOrDefault();        var attributes = actionDescriptor?.MethodInfo.GetCustomAttributes(typeof(TAttribute), false).Cast<TAttribute>();        return attributes;    }        return null;}

千巷猫影

从 .net 5 开始,上下文是HttpContext有GetEndPoint方法扩展HttpContextprotected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement){    if(context is HttpContext httContext){        var endpoint = context.GetEndPoint();    } else {        throw ... // let's see how things will move with next version of .net     }}

元芳怎么了

有一个部分“在处理程序中访问 MVC 请求上下文”,但这是错误的。然而,在“反馈”下,他们的 2 个问题看起来与最有希望的答案相关,即将下面的代码添加到AuthorizationHandler.这可以访问controllerActionDescriptor,但正如你所看到的,我已经查看了各种属性,但没有一个属性给我当前的路由数据:var controllerActionDescriptor = routeEndpoint.Metadata    .OfType<ControllerActionDescriptor>()    .SingleOrDefault();if (controllerActionDescriptor != null){    var a = controllerActionDescriptor.AttributeRouteInfo;    var p = controllerActionDescriptor.Parameters;    var ep = controllerActionDescriptor.EndpointMetadata;    var r = controllerActionDescriptor.RouteValues;}

慕莱坞森

我找到了解决方案,在ConfigureServices中将IHttpContextAccessor注册到IOC中services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();然后在AttributeAuthorizationHandler中获取public class AccountLoginAuthorizeHandler : AttributeAuthorizationHandler<AccountLoginAuthorizationRequirement, AccountLoginAttribute>{&nbsp; &nbsp; private readonly IHttpContextAccessor _httpContextAccessor;&nbsp; &nbsp; public PermissionAuthorizeHandler(IHttpContextAccessor httpContextAccessor, IZaabeeRedisClient redisClient,&nbsp; &nbsp; IOptions<LoginConfig> loginConfig)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));&nbsp; &nbsp; }&nbsp; &nbsp; protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AccountLoginAuthorizationRequirement requirement, IEnumerable<AccountLoginAttribute> attributes)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (context.Resource is AuthorizationFilterContext filterContext)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var httpContext = _httpContextAccessor.HttpContext;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Do Something&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Do Something&nbsp; &nbsp; &nbsp; &nbsp; context.Succeed(requirement);&nbsp; &nbsp; &nbsp; &nbsp; return Task.CompletedTask;&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP