Search code examples
c#.netcontroller

How to disable a route (or allow duplicates) from the parent controller class


I want a child controller to have query parameters while the default implementation in the base controller has none. I have a base controller that all other controllers inherit from. The controller has a Get() method:

public abstract class BaseEntityController : Controller
{
  [HttpGet]
  [Route("")]
  public virtual Task<IActionResult> Get()
  {
      DoSomeGetAllFunctionallity();
  }
}

In one of the child controllers I want to have some query parameters in the for the get all method:

public abstract class ChildController : BaseEntityController
{
  [HttpGet]
  [Route("")]
  public async Task<IActionResult> Get([FromQuery(Name = "param-1")] int? param1, [FromQuery(Name = "param-2")] bool param2 = false)
  {
    DoSomeGetAllFunctionallity(param1, param2);
  }
}

When trying to test this with Swagger I get the error:

Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: 'Conflicting method/path combination "GET endpoint" for actions - path-to-controller.Get, path-to-controller.Get. Actions require a unique method/path combination for Swagger/OpenAPI 3.0. Use ConflictingActionsResolver as a workaround'

I would be happy with the following two outcomes:

  1. Override the route of the base class to disable it
[Route(disable: true)]
public override Task<IActionResult> Get() => throw new NotImplementedException();
  1. Pass the default parameters through to the other method
public override Task<IActionResult> Get() => Get(null, false);

I have not found a solution for either of the two outcomes.


Solution

  • I found an answer that works for me. An action method can be disabled by adding the [NonAction] attribute. This way the child controller can disable the parent action method and make its own for the same route.

    public abstract class ChildController : BaseEntityController
    {
      [NonAction]
      public override Task<IActionResult> Get() => throw new NotImplementedException();
    
      [HttpGet]
      [Route("")]
      public async Task<IActionResult> Get([FromQuery(Name = "param-1")] int? param1, [FromQuery(Name = "param-2")] bool param2 = false)
      {
        DoSomeGetAllFunctionallity(param1, param2);
      }
    }