0

I develop WebAPI application and I need to use a custom controller selector, so I have created this one:

public class CustomControllerSelector : DefaultHttpControllerSelector
{
    (...)
    
    public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
    {
        // It's just a simplified logic which exemplify the problem
        var controller =_controllerAssembly.GetType("App.Controllers.MyController");
        return new HttpControllerDescriptor(this.httpConfiguration, controller.Name, controller);
    }
}

My controller contains two GET methods:

public class MyController : System.Web.Http.ApiController
{
    [Route("~/api/myController/GetAll")]
    public IEnumerable<MyModel> GetAll(){ ... }

    public MyModel Get(){ ... }
}

Unfortunately, when I go to http://localhost/api/myController/, I get the error:

Multiple actions were found that match the request:

GetAll on type App.Controllers.MyController

Get on type App.Controllers.MyController"

But if I go to http://localhost/api/myController/GetAll, it works as intended and collection of object is returned.

It is worth mentioning that if I don't use the custom controller selector, it works like a charm and both actions gives valid response.

Do you know why custom controller selector (derived from default selector) causes this problem?

Workaround:

Since the original (default) controller selector is initialized properly and works as expected, I aggregate it instead of inherit from it.

class CustomControllerSelector : IHttpControllerSelector 
{ 
    private DefaultHttpControllerSelector defaultSelector; 

    public CustomControllerSelector(DefaultHttpControllerSelector defaultSelector)
    { 
        (...) 
}
Community
  • 1
  • 1
gis
  • 141
  • 11
  • Also `http://localhost/api/myController/get` will work. Yes? – Ramin Bateni Jan 26 '18 at 09:01
  • No, it doesn't, because I use default WebAPI routing configuration: ` `config.MapHttpAttributeRoutes(); (...) routeTemplate: "api/{controller}/{id}" (...)` – gis Jan 26 '18 at 09:06
  • I'm sorry, but I didn't mention that I had also `Get(int id)` action. Nevertheless, I remove this method and I get the same result as I described in my post (`api/myController/get` causes error if I use custom selector, otherwise it works properly). – gis Jan 26 '18 at 09:19
  • Dose not `MyController` inherited from `ApiController` in your project? – Ramin Bateni Jan 26 '18 at 09:20
  • Actually, it does. I've corrected my post. – gis Jan 26 '18 at 09:22
  • For a test put this rout attribute over Get method and run: `[Route("~/api/myController/Get")]` – Ramin Bateni Jan 26 '18 at 09:31
  • OK, I did that. `api/myController/Get` works properly; `api/myController/GetAll` works properly; `api/myController/` doesn't work (error _Multiple actions..._ is displayed) – gis Jan 26 '18 at 09:38
  • I suggest you read this [QA](https://stackoverflow.com/questions/19835015/versioning-asp-net-web-api-2-with-media-types). Follow it. I hope it help. – Ramin Bateni Jan 26 '18 at 10:05
  • Thank you. I've checked it, but I've not found the satisfying answer. Nevertheless, it's helped me to find the workaround. – gis Feb 11 '18 at 13:21

0 Answers0