Dimitri Sauvage
Dimitri Sauvage

Reputation: 33

ASP Net Core - How to make route inheritance on multiple level?

I'm working on an API, and I have the following problem

I have abstract ApiController, like this

public abstract class ApiController<TService> : ApiController
    where TService : BaseService
{
    #region Fields

    /// <summary>
    /// Data manager
    /// </summary>
    protected TService Service { get; } = ServiceCollectionHelper.GetElementFromDependencyInjection<TService>();

    #endregion

    #region Constructors

    #endregion
}

[ApiController]
[Authorize]
[Produces("application/json")]
[Route("api", Name = "BaseApiRoute")]
public abstract class ApiController : ControllerBase
{
}

I have multiple controllers, which inherit ApiController<TService>, or ApiController.

Example Controllers :

[Route("[controller]")]
public class RegionsController : ApiController<RegionService>
{
    #region Fields

    #endregion

    #region Constructor

    #endregion

    #region Methods

    /// <summary>
    /// Get the regions
    /// </summary>
    /// <param name="includeDepartments">Include the region departments</param>
    /// <returns>Regions</returns>
    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable<DepartmentDTO>), StatusCodes.Status200OK)]
    public async Task<ActionResult<IEnumerable<RegionDTO>>> GetAsync(bool includeDepartments = false)
    {
        return this.Ok(await this.Service.GetAsync(includeDepartments));
    }

    #endregion
}

Normally, the route for the method RegionsController.GetAsync should be /api/regions with GET method, but it is /regions

Why the inheritance doesn't work, and how to correct that to have the /api prefix for all routes ?

I have tried to replace [Route("/api")] with [Area("/api')] but it didn't work.

Thanks

Upvotes: 2

Views: 1548

Answers (1)

weichch
weichch

Reputation: 10065

If you define [Route("[controller]")] on RegionsController, it overrides the base route.

Instead, you could define route with token replacement on base controller like:

[ApiController]
[Authorize]
[Produces("application/json")]
[Route("api/[controller]", Name = "BaseApiRoute_[controller]")]
public abstract class ApiController : ControllerBase
{
}

See token replacement and route inheritance for more information.

Attribute routes can also be combined with inheritance. This is powerful combined with token replacement. Token replacement also applies to route names defined by attribute routes.

Upvotes: 2

Related Questions