Home > Back-end >  ASP.NET core how to add a base controller action
ASP.NET core how to add a base controller action

Time:08-12

I am looking to add a base action that will be triggered at first before some of other actions, that is similar to the middleware concept in Node.js where one route will match one action by another action until the request is fulfilled and then later actions will not be triggered.

Like:

public class MyController : ControllerBase
    {
        public ReportDetailController(){}

        [HttpGet]
        [Route("get")]
        public ActionResult one()
        {
            // base action
            // do some process base on request info
            // then
            return Next();
        }

        [HttpGet]
        [Route("get")]
        public ActionResult two()
        {
            // base action
            // do some process base on request info
            // then
            return Next();
        }

        [HttpGet]
        [Route("get")]
        public ActionResult three()
        {
            // fulfill here
            return Ok();
        }

        [HttpGet]
        [Route("get")]
        public ActionResult three()
        {
            // will not come here
            return Ok();
        }
    }
}

Is it possible to achieve this kind of operations in ASP.NET core? the base action need to be able to access the Request object information for pre-processing.

CodePudding user response:

Yes, you can do this. Either you can create Middleware - or you can use ActionFilterAttribute. Since you already using a BaseController you can override the OnActionExecutionAsync method or OnActionExecuting method.

Here is an example which adds the Bearer token to HttpClient

public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
    if (User.Identity!.IsAuthenticated)
    {
        var idToken = await HttpContext.GetTokenAsync("id_token");
        _httpClient.DefaultRequestHeaders.Accept.Clear();
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", idToken);
    }

    await base.OnActionExecutionAsync(context, next);
}

CodePudding user response:

To make an action call before the target action, or fullfill request before that, we need to use Controller class instead of ControllerBase since Controller implements IActionFilter and so you can override the OnActionExecuting method, which is a method that will be called before an endpoint action.

so,

public class MyController : Controller
{
    public MyController(){}

    [NonAction]
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if(!user.exist)
        {
            // this will fulfill response
            // prevent actions below from being executed
            var re = new NotFoundObjectResult("Invalid User");
            context.Result = re;
        }
        else
        {
            // go to target action
        }
    }
        
    [HttpGet]
    public ActionResult Target()
    {
        // will come here
        return Ok();
    }
}
  • Related