Search code examples
c#asp.net-mvcapihandlerinterceptor

How to intercept GET request in api before execution in ASP.NET?


I'm trying to figure out how to intercept a GET call before execution occurs in .NET framework.

I've created 2 applications: a front-end(calls the API and sends custom HTTP headers with it) and a back-end API:

Front-end method which calls API:

[HttpGet]
    public async Task<ActionResult> getCall()
    {
        string url = "http://localhost:54857/";
        string customerApi = "2";

        using (var client = new HttpClient())
        {
            //get logged in userID
            HttpContext context = System.Web.HttpContext.Current;
            string sessionID = context.Session["userID"].ToString();

            //Create request and add headers
            client.BaseAddress = new Uri(url);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            //Custom header
            client.DefaultRequestHeaders.Add("loggedInUser", sessionID);

            //Response
            HttpResponseMessage response = await client.GetAsync(customerApi);
            if (response.IsSuccessStatusCode)
            {
                string jsondata = await response.Content.ReadAsStringAsync();
                return Content(jsondata, "application/json");
            }
            return Json(1, JsonRequestBehavior.AllowGet);
        }
    }

Back-end which receives the request:

public class RedirectController : ApiController
{
    //Retrieve entire DB
    ConcurrentDBEntities dbProducts = new ConcurrentDBEntities();

    //Get all data by customerID
    [System.Web.Http.AcceptVerbs("GET")]
    [System.Web.Http.HttpGet]
    [System.Web.Http.Route("{id}")]
    public Customer getById(int id = -1)
    {
        //Headers uitlezen
        /*var re = Request;
        var headers = re.Headers;

        if (headers.Contains("loggedInUser"))
        {
            string token = headers.GetValues("loggedInUser").First();
        }*/

        Customer t = dbProducts.Customers
            .Where(h => h.customerID == id)
            .FirstOrDefault();
        return t;
    }
}

Routing:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

The code shown above works fine, I'm getting the correct results of my API call but I'm looking for a way to intercept all of the incoming GET request before im returning a response so i can modify and add logic to this controller. While making my GET request i add custom headers, I'm looking for a way to extract these from the incoming GET all before execution occurs.

Hope someone can help!

Thanks in advance


Solution

  • ActionFilterAttribute, used as in the following example, I created the attribute and put it on the api base class where all api classes inherit from, OnActionExecuting is entered before reaching the api method. we can check there if the RequestMethod is of "GET" and do whatever you are planning to do there.

    public class TestActionFilterAttribute: ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.Request.Method.Method == "GET")
            {
                //do stuff for all get requests
            }
            base.OnActionExecuting(actionContext);
        }
    }
    
    [TestActionFilter] // this will be for EVERY inheriting api controller 
    public class BaseApiController : ApiController
    {
    
    }
    
    [TestActionFilter] // this will be for EVERY api method
    public class PersonController: BaseApiController
    {
        [HttpGet]
        [TestActionFilter] // this will be for just this one method
        public HttpResponseMessage GetAll()
        {
            //normal api stuff
        }
    }