Why is it so hard to get an ActionName in ApiController? Easier?

The MVC controller gets the action name and controller name:

public class AuthorizeController : Controller
{

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string actionName = filterContext.ActionDescriptor.ActionName;
        string controllerNamespace = filterContext.ActionDescriptor.ControllerDescriptor.ControllerType.FullName;
        //..more code
        base.OnActionExecuting(filterContext);
    }
}

Pretty straight forward.

But when I have ApiController ( System.Web.Http.ApiController), things get more complicated:

enter image description here

In the end, with some rsharper tips, I was able to reduce it to a few lines.

private string GetActionName(HttpControllerContext context)
{
    var httpRouteDataCollection = context.RouteData.Values.Values;
    var httpRouteDataCollection2 = httpRouteDataCollection.FirstOrDefault();
    if (!(httpRouteDataCollection2 is IHttpRouteData[] httpRouteData))
    {
        return null;
    }

    IHttpRouteData routeData = httpRouteData.FirstOrDefault();
    var httpActionDescriptorCollection = routeData?.Route.DataTokens["actions"];
    if (!(httpActionDescriptorCollection is HttpActionDescriptor[] httpActionDescriptor))
    {
        return null;
    }
    HttpActionDescriptor reflectedHttpActionDescriptor = httpActionDescriptor.FirstOrDefault();
    return reflectedHttpActionDescriptor?.ActionName;
}

Is it easier to do this? The reason for this is because I am currently implementing a general way of determining who can discover which action. Some actions are within WebApi and every time I need to execute the above “request”. Thus, all this turns things into a while.

WHY?

, , 40 MVC- 20 API 5-10 . ( ) Identity. , . , , .

+4
2

ActionFilterAttribute:

public class ValidateAccessAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var actionName = actionContext.ActionDescriptor.ActionName;
        ......
        base.OnActionExecuting(actionContext);
    }
}

:

    [ValidateAccess]
    public async Task<IHttpActionResult> Stuff()

"", , , , . .

,

public class ValidateAccessAttribute2 : ActionFilterAttribute
{
    private readonly FunctionalArea _area;

    public ValidateAccessAttribute2(FunctionalArea area)
    {
        _area = area;
    }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        base.OnActionExecuting(actionContext);
        if (!actionContext.Request.Headers.Contains(AuthorizationHeaders.UserNameHeader))
        {
            actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            return;
        }
        var userName = actionContext.Request.Headers.GetValues("UserNameHeader").First();
        if (!UserCanAccessArea(userName, _area))
        {
            actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            return;
        }
    }
}


    [ValidateAccess2(FunctionalArea.AccessToGenericStuff)]
    public async Task<IHttpActionResult> Stuff()
+3

ActionContext ControllerContext?

public class ValuesController : ApiController
{
    [HttpGet]
    [AllowAnonymous]
    public IHttpActionResult Get()
    {
        var actionName = this.ActionContext.ActionDescriptor.ActionName;
        var controlerName = this.ControllerContext.ControllerDescriptor.ControllerName;
        return this.Ok();
    }
}
+2

Source: https://habr.com/ru/post/1694324/


All Articles