Attribute routing not working when controller is loaded dynamically (using custom controller selector) RRS feed

  • Question

  • I'm creating a self hosted REST server (using Owin):

    string baseUri = string.Concat("http://+:12345/MyServer");
    myserver = WebApp.Start<Startup>(baseUri);
    Console.WriteLine("MyServer is listening at " + baseUri);

    I create a static controller just to make sure it works ok with my settings:

    public class SampleController : ApiController
        public SampleController() { }
        public string GetTest(string data)
            return Test(data);
        public string Test([FromBody] string data)
            return string.Concat("Test - Received ", data);

    My startup class looks like this:

    public class Startup
        public void Configuration(IAppBuilder app)
            var webApiConfiguration = ConfigureWebApi();
        private HttpConfiguration ConfigureWebApi()
            HttpConfiguration config = new HttpConfiguration();
                        new { id = RouteParameter.Optional});
            DynControllerSelector custom = new DynControllerSelector(config);
            config.Services.Replace(typeof(IHttpControllerSelector), custom);
            return config;

    Then i dynamically load another controller which has the same methods and definition exposed than the static one. To do that i use a custom controller selector:

    public DynControllerSelector(HttpConfiguration configuration) : base(configuration)
        _Configuration = configuration;
        _ControlleDescriptorDict = new ConcurrentDictionary<string, HttpControllerDescriptor>();
     public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        HttpControllerDescriptor httpControllerDesc = null;
          IDictionary<string, HttpControllerDescriptor> controllers = GetControllerMapping();
          //string controllerName = base.GetControllerName(request); // is null for some reason
         // Just get the controler in a hack way for now
        string controllerName = request.RequestUri.LocalPath.Replace("/MyServer/api/", "");
        int idx = controllerName.IndexOf("/");
        controllerName = controllerName.Substring(0, idx);
        if (!controllers.ContainsKey(controllerName))
           if (_ControlleDescriptorDict.TryGetValue(controllerName, out httpControllerDesc) == false)
            lock (_mlock)
                if (_ControlleDescriptorDict.TryGetValue(controllerName, out httpControllerDesc) == false) // Check that controller has not been created while we were waiting for the lock
                  string assemblyName = string.Concat(controllerName, ".dll");
                  if (System.IO.File.Exists(assemblyName))
                     Assembly assembly = Assembly.LoadFrom(assemblyName);
                     var types = assembly.GetTypes();
                     var matchedTypes = types.Where(i => typeof(IHttpController).IsAssignableFrom(i)).ToList();
                     var matchedController = matchedTypes.FirstOrDefault(i => i.Name.ToLower() == controllerName.ToLower() + "controller");
                     if (matchedController == null) throw new Exception(string.Concat("Failed to find controller ", controllerName, "Controller"));
                     httpControllerDesc = new HttpControllerDescriptor(_Configuration, controllerName, matchedController);
                    _ControlleDescriptorDict.TryAdd(controllerName, httpControllerDesc);
                    throw new Exception(string.Concat("Failed to load assembly ", assemblyName));
                httpControllerDesc = base.SelectController(request);
    . . 

    They should both use the same routing settings.

    I can call (HTTP GET) my static controller using attribute routing: http://localhost:12345/MyServer/api/Sample/Test/hello2 
    That works fine.

    Problem is when i try the same thing on my dynamic controller: http://localhost:12345/MyServer/api/MyDynamic/Test/hello2 

    I get following error: { "Message": "The requested resource does not support http method 'GET'." }

    It seems somehow the attribute routing is not enabled for my dynamic controller. If i use query parameters, it works just fine: http://localhost:12345/MyServer/api/MyDynamic/Test?data=hello

    How can i make it work?

    Thanks in advance for your help


    • Moved by CoolDadTx Wednesday, October 16, 2019 5:22 PM ASP.NET related
    Wednesday, October 16, 2019 8:38 AM

All replies

  • Please post questions related to web development in the ASP.NET forums.

    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, October 16, 2019 5:21 PM