Search code examples
wcfasp.net-web-api

Execute code before (EVERY) Web API action


I have a Web API interface I'm trying to adapt to a multi-tenant architecture. Previously, we had a WCF mode whereby we passed a parameter, client ID, to the service, which then stored this for use in the code later. This meant that Client ID didn't have to be the first parameter passed to every call.

I'd like to do the same with Web API, i.e., rather than having:

GetDocument(int clientId, int documentId)
GetDefault(int clientId)
GetImage(int clientId, int imageId)

have just:

GetDocument(int documentId)
GetDefault()
GetImage(int imageId)

But I need some way to do the following:

  1. Get the clientId from the route
  2. Put this value into the state object I've got

All before the call actually executes. I'm kind of thinking that the route will get rewritten - I'm fine with the route having to have the client id in it, just not my API. So the call to GetDefault might look like:

/Document/GetDefault/1

while the API is:

GetDefault()

How can I achieve this?


Solution

  • One approach would be a custom ActionFilter. See here, although it's about MVC the concept is identical to WebAPI:

    ASP.NET MVC provides Action Filters for executing filtering logic either before or after an action method is called. Action Filters are custom attributes that provide declarative means to add pre-action and post-action behavior to the controller's action methods.

    For example:

        public class MyActionFilter : ActionFilterAttribute
        {
            public override void OnActionExecuting(HttpActionContext actionContext)
            {
               //....
            }
    
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
               //....
            }
        }
    

    And use that do decorate your API controllers/actions:

        [MyActionFilter]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }