Friday, June 5, 2015

MS caches query parameters in WebAPI 2.0

ASP.NET WebAPI extensibility is actually quite simple to implement thought the use of Filters and MessageHandlers. However, looking at the WebAPI HTTPMessage LifeCycle, you can see that only one filter occurs before ModelBinding:

ASP.NET WebAPI Page LifeCycle

(click to enlarge)

So, to do something like Form to URL Encoded (application/x-www-form-urlencoded) you either use the Authorization Filter or MessageHandlers. Taking this scenario, imagine you have a parameter in the body like:
Source = 'CA'

But, your Controller is expecting this parameter in the URL:

Parameter URL WebAPI

(click to enlarge)

To do this before the ModelBinding happens, you either do the trick and use the AuthorizationFilter or implement a MessageHandler. The first option is a kind of "Hack" since you're not actually doing authorization logic, but it works. In our scenario, we want to do something like this (ignore the "hammer code", it's the simplest to illustrate):

Change URI WebAPI Filter

(click to enlarge)

Now, there's an extra hack. Microsoft caches the Query parameters in a varsbag and uses those cached parameters in the ModelBinders (e.g.: my TimeBinder in the above example). So, altering any request URI won't have any effect until you clear the "cached params":

new StringContent

(click to enlarge)

After you do this, you can alter the RequestUri (although this is not a good practice). This only works on WebAPI 2.0. Here's more info: