为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
沧海一幻觉 2023-07-23 16:47:57
我已将 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>();        }    }}
查看完整描述

4 回答

?
狐的传说

TA贡献1804条经验 获得超3个赞

我能够通过在AuthorizationHandlerContext中使用来获取 .NET Core 3.1 中的自定义属性。ControllerActionDescriptor


private 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;

}




查看完整回答
反对 回复 2023-07-23
?
千巷猫影

TA贡献1829条经验 获得超7个赞

从 .net 5 开始,上下文是HttpContext

GetEndPoint方法扩展HttpContext

protected 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 

    }

}


查看完整回答
反对 回复 2023-07-23
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

有一个部分“在处理程序中访问 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;

}


查看完整回答
反对 回复 2023-07-23
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

我找到了解决方案,在ConfigureServices中将IHttpContextAccessor注册到IOC中


services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

然后在AttributeAuthorizationHandler中获取


public class AccountLoginAuthorizeHandler : AttributeAuthorizationHandler<AccountLoginAuthorizationRequirement, AccountLoginAttribute>

{

    private readonly IHttpContextAccessor _httpContextAccessor;

    public PermissionAuthorizeHandler(IHttpContextAccessor httpContextAccessor, IZaabeeRedisClient redisClient,

    IOptions<LoginConfig> loginConfig)

    {

        _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));

    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AccountLoginAuthorizationRequirement requirement, IEnumerable<AccountLoginAttribute> attributes)

    {

        if (context.Resource is AuthorizationFilterContext filterContext)

        {

            var httpContext = _httpContextAccessor.HttpContext;

            //Do Something

        }

        else

            //Do Something


        context.Succeed(requirement);

        return Task.CompletedTask;

    }

}


查看完整回答
反对 回复 2023-07-23
  • 4 回答
  • 0 关注
  • 173 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信