public class VersionAwareControllerSelector : DefaultHttpControllerSelector
{
    private const string VERSION_HEADER_NAME = "some-value";
    private const string VERSION_QUERY_NAME = "v";
    private HttpConfiguration _configuration;
    public VersionAwareControllerSelector(HttpConfiguration configuration)
        : base(configuration)
    {
        _configuration = configuration;
    }
    // This works for Web API 2 and Attributed Routing
    // FROM: http://stackoverflow.com/questions/19835015/versioning-asp-net-web-api-2-with-media-types/19882371#19882371
    // BLOG: http://webstackoflove.com/asp-net-web-api-versioning-with-media-types/
    public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
    {
        HttpControllerDescriptor controllerDescriptor = null;
        // Get a list of all controllers provided by the default selector
        IDictionary<string, HttpControllerDescriptor> controllers = GetControllerMapping();
        IHttpRouteData routeData = request.GetRouteData();
        if (routeData == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        // Pick up the API Version from the header...but we could also do query string
        var apiVersion = GetVersionFromHeader(request);
        // Check if this route is actually an attribute route
        IEnumerable<IHttpRouteData> attributeSubRoutes = routeData.GetSubRoutes();
        if (attributeSubRoutes == null)
        {
            string controllerName = GetRouteVariable<string>(routeData, "controller");
            if (controllerName == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            string newControllerName = String.Concat(controllerName, apiVersion);
            if (controllers.TryGetValue(newControllerName, out controllerDescriptor))
            {
                return controllerDescriptor;
            }
            else
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
        }
        else
        {
            string newControllerNameSuffix = String.Concat("V", apiVersion); ;
            IEnumerable<IHttpRouteData> filteredSubRoutes = attributeSubRoutes.Where(attrRouteData =>
            {
                HttpControllerDescriptor currentDescriptor = GetControllerDescriptor(attrRouteData);
                bool match = currentDescriptor.ControllerName.EndsWith(newControllerNameSuffix);
                if (match && (controllerDescriptor == null))
                {
                    controllerDescriptor = currentDescriptor;
                }
                return match;
            });
            routeData.Values["MS_SubRoutes"] = filteredSubRoutes.ToArray();
        }
        return controllerDescriptor;
    }
    private HttpControllerDescriptor GetControllerDescriptor(IHttpRouteData routeData)
    {
        return ((HttpActionDescriptor[])routeData.Route.DataTokens["actions"]).First().ControllerDescriptor;
    }
    // Get a value from the route data, if present.
    private static T GetRouteVariable<T>(IHttpRouteData routeData, string name)
    {
        object result = null;
        if (routeData.Values.TryGetValue(name, out result))
        {
            return (T)result;
        }
        return default(T);
    }
    
    private string GetVersionFromHeader(HttpRequestMessage request)
    {
        if (request.Headers.Contains(VERSION_HEADER_NAME))
        {
            var header = request.Headers.GetValues(VERSION_HEADER_NAME).FirstOrDefault();
            if (header != null)
            {
                return header;
            }
        }
        return "1";
    }
    private string GetVersionFromQueryString(HttpRequestMessage request)
    {
        var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
        var version = query[VERSION_QUERY_NAME];
        if (version != null)
        {
            return version;
        }
        return "1";
    }
}