Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.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
C# asp net核心mvc中的路由段解析_C#_Asp.net_Asp.net Mvc_Asp.net Core_Asp.net Mvc Routing - Fatal编程技术网

C# asp net核心mvc中的路由段解析

C# asp net核心mvc中的路由段解析,c#,asp.net,asp.net-mvc,asp.net-core,asp.net-mvc-routing,C#,Asp.net,Asp.net Mvc,Asp.net Core,Asp.net Mvc Routing,我想在自定义属性中进行安全验证。一个很好的例子是,如果用户发出GET请求以检索具有给定id的实体,我希望在属性中拦截该请求,将其交给操作筛选器,然后确定用户是否有权访问该请求。我唯一的问题是如何检索实体id。我不能在属性声明中传递它,因为它会初始化一次,而不是每次请求。相反,我想给我的自定义属性一个url模式,就像给HttpGet或HttpPost一样,并让它根据上下文的url参数进行解析,以生成实体id 以下是我的属性: public class RequireProjectAccessAtt

我想在自定义属性中进行安全验证。一个很好的例子是,如果用户发出GET请求以检索具有给定id的实体,我希望在属性中拦截该请求,将其交给操作筛选器,然后确定用户是否有权访问该请求。我唯一的问题是如何检索实体id。我不能在属性声明中传递它,因为它会初始化一次,而不是每次请求。相反,我想给我的自定义属性一个url模式,就像给HttpGet或HttpPost一样,并让它根据上下文的url参数进行解析,以生成实体id

以下是我的属性:

public class RequireProjectAccessAttribute : TypeFilterAttribute
{
    public string UrlPattern { get; set; }
    public RequireProjectAccessAttribute(string urlPattern) : base(typeof(RequireProjectAccessFilter))
    {
        UrlPattern = urlPattern;
        Arguments = new object[] { urlPattern };
    }

    private class RequireProjectAccessFilter : IAsyncActionFilter
    {
        private readonly ICurrentSession _currentSession;
        private readonly string _urlPattern;

        public RequireProjectAccessFilter(ICurrentSession currentSession, string urlPattern)
        {
            _currentSession = currentSession;
            _urlPattern = urlPattern;
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var projectId = /* some magic to resolve _urlPattern against the current url parameter values */
            if (/* user doesn't have access to project */)
            {
                context.Result = new UnauthorizedResult();
            }
            else
            {
                await next();
            }
        }
    }
}
下面是我想如何使用它:

[Route("api/[controller]")]
public class ProjectsController : BaseController
{

    public ProjectsController()
    {
    }

    [RequireProjectAccess("{projectId}")]
    [HttpGet("{projectId}")]
    public JsonResult GetById(int projectId)
    {
        /* retrieve project */
    }
}

您只需要提供包含该值的路由键,然后在
HttpContext
对象上使用扩展方法

var projectId = context.HttpContext.GetRouteValue(_routeKey)?.ToString();
这意味着您的属性将如下所示:

public class RequireProjectAccessAttribute : TypeFilterAttribute
{
    public string RouteKey { get; set; }
    public RequireProjectAccessAttribute(string routeKey) : base(typeof(RequireProjectAccessFilter))
    {
        RouteKey = routeKey;
        Arguments = new object[] { routeKey };
    }

    private class RequireProjectAccessFilter : IAsyncActionFilter
    {
        private readonly ICurrentSession _currentSession;
        private readonly string _routeKey;

        public RequireProjectAccessFilter(ICurrentSession currentSession, string routeKey)
        {
            _currentSession = currentSession;
            _routeKey = routeKey;
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var projectId = context.HttpContext.GetRouteValue(_routeKey)?.ToString();
            if (/* user doesn't have access to project */)
            {
                context.Result = new UnauthorizedResult();
            }
            else
            {
                await next();
            }
        }
    }
}
如下所示(注意,我只传递路由密钥的名称):


https://channel9.msdn。com/Blogs/Seth Juarez/Advanced aspNET Core Authorization with Barry Dorrans |转到本视频并跳到大约30分钟。这很接近,但我想以与HttpGet解析其论点完全相同的方式解析传入RequireProjectAccess的内容。我不想传递“projectId”,我想传递“{projectId}”,让MVC使用其内部路由解析器使用正确的URL参数来解析它。我想我遗漏了一些东西。既然路由已经解析了“{projectId}”,并使projectId参数在RouteData中可用,为什么需要再次解析它?
[RequireProjectAccess("projectId")]
[HttpGet("{projectId}")]
public JsonResult GetById(int projectId)
{
    /* retrieve project */
}