I want to know if there's a way to create subclasses that act as a routing group for an api using AspNetCore Mvc.
These are the routes I need to use.
api/speak
api/dance/tango
api/dance/salsa
api/sing/song
api/sing/tune
[Route("api")]
[ApiController]
public class ApiController: Controller Base {
private IMyService myService;
public ApiController(IMyService myService) {
this.myService = myService;
}
[Route("dance")] // This is what I want to do, create a sub-route "group"
public class Dance {
[HttpGet("tango")]
public async Task<IActionResult> Tango() {
return Okay(myService.TangoDance());
}
[HttpGet("salsa")]
public async Task<IActionResult> Salsa() {
return Okay(myService.alsaDance());
}
}
[Route("sing")] // And create a second sub-route "group" in the controller
public class Dance {
[HttpGet("song")]
public async Task<IActionResult> Song() {
return Okay(myService.SingSong());
}
[HttpGet("tune")]
public async Task<IActionResult> Tune() {
return Okay(myService.SingTune());
}
}
[HttpGet("speak")]
public async Task<IActionResult> Speak() {
return Okay(myService.Words());
}
}
In the code above myService
doesn't work in the subclasses. I used that code as I felt it explained best what I want to accomplish. (I had the subclasses inherit ApiController
so that I could use myService
inside those methods but that didn't fix the routes not working.)
The reason I'm on stack overflow is because I can't get this to work, and I can't find anything online.
I'm using Swagger to test the routes, that's how I can see that they're not showing up.
All help is greatly appreciated.
These would be separate controllers. There's a good argument for doing it this way (idiomatically), anyone with experience would instantly recognise the pattern and know exactly how things work.
You would use a base controller to capture the service dependency:
[ApiController]
public abstract class MyBaseController: ControllerBase {
protected IMyService myService;
public MyBaseController(IMyService myService) {
this.myService = myService;
}
}
And then implement the controllers like so, passing the (injected) dependency down to your base controller:
[Route("api/[controller]")]
public class SpeakController: MyBaseController {
public SpeakController(IMyService myService) : base(myService)
{
}
[HttpGet] // GET api/speak
public async Task<IActionResult> Index()
{
return Okay(myService.Words());
}
}
[Route("api/[controller]")]
public class DanceController: MyBaseController {
public DanceController(IMyService myService) : base(myService)
{
}
[HttpGet] // GET api/dance/tango
public async Task<IActionResult> Tango() {
return Okay(myService.TangoDance());
}
[HttpGet] // GET api/dance/salsa
public async Task<IActionResult> Salsa() {
return Okay(myService.alsaDance());
}
}
[Route("api/[controller]")]
public class SingController: MyBaseController {
public SingController(IMyService myService) : base(myService)
{
}
[HttpGet] // GET api/sing/song
public async Task<IActionResult> Song() {
return Okay(myService.SingSong());
}
[HttpGet] // GET api/sing/tune
public async Task<IActionResult> Tune() {
return Okay(myService.SingTune());
}
}