11

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?

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Chris B. Behrens
  • 6,255
  • 8
  • 45
  • 71
  • You could try a custom `ActionFilter`, or even a `MessageHandler`. – Mohammad Sepahvand Jun 27 '14 at 21:57
  • I quickly mocked up an approach using the querystring for the clientid, and it seems to be working, but there's no session state, which is where I was putting the client id. I suspect that this is an order of operations thing, whereby the session state doesn't exist when the MessageHandler is fired. The session state works fine later on (I've specified a HttpControllerHandler that implements IRequiresSessionState)... – Chris B. Behrens Jun 27 '14 at 22:17
  • Your comment is a satisfactory answer to my question, my next barrier notwithstanding. Add it as an answer and I'll accept it. – Chris B. Behrens Jun 30 '14 at 01:20

1 Answers1

24

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" };
    }
Mohammad Sepahvand
  • 17,364
  • 22
  • 81
  • 122