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();
}
}