Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute:

I want to use URL-Based versioning for my controller. best solution that I found was code below. I'm looking for better solution for this. I tried Constrain It didn't work maybe i did some thing wrong my only concern is using controller with same name in different namespace...?! I userd string merging to creating wanted type. probably it is not a good idea. Please send good reference for this topic if you know any.....?

public class ControllerVersioning : DefaultHttpControllerSelector
    {
        private HttpConfiguration _config;
        public ControllerVersioning(HttpConfiguration config)
            : base(config)
        {
            _config = config;
        }

        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            var routeData = request.GetRouteData();

            var controllerName = routeData.Values["controller"].ToString();
            controllerName = char.ToUpper(controllerName[0]) + controllerName.Substring(1); 
            var versionName = routeData.Values["version"].ToString();

            HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor();
            controllerDescriptor.Configuration = _config;
            controllerDescriptor.ControllerName = controllerName;

            string s = "ngolforoushan.Web.Api.Controllers.V" + versionName + "." + controllerName + "Controller";
            Type t=Type.GetType(s);
            controllerDescriptor.ControllerType = t;

            return controllerDescriptor;

        }
    }
share|improve this question
    
Take a look at the VersionedRoute attribute as implemented here: aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/… – Jeroen Vannevel Apr 5 at 21:09
    
Thanks for reply but, codeplex code was related to controller with different names that's easy ;-) – Navid Golforoushan Apr 6 at 5:13

1 Answer 1

var dictionary = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase);

    var assembliesResolver = _config.Services.GetAssembliesResolver();
    var controllerResolver = _config.Services.GetHttpControllerTypeResolver();

    var controllerTypes = controllerResolver.GetControllerTypes(assembliesResolver);

    foreach (var cType in controllerTypes)
    {
        var segments = cType.Namespace.Split(Type.Delimiter);

        var controllerName = cType.Name.Remove(cType.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length);

        var controllerKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", segments[segments.Length - 1], controllerName);
        if (!dictionary.Keys.Contains(controllerKey))
        {
            dictionary[controllerKey] = new HttpControllerDescriptor(_config, cType.Name, cType);
        }
    }

This is the way that you can return list of all controller on your Assembly and put all of them to a dictionary.

based on my code above-I mean thread topic, my first post- you know how you can get {version,controller} and selected related controller and passing it as a parameter.

I added code below to make it easier to fetch version and controller but you need to know if you have different route which they are not related to versioning you need to check before assign version and controller strings.

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{version}/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
share|improve this answer
    
What would the naming convention for the controllers or methods in order to implement this? – lorddev Dec 3 at 19:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.