The problem
When I create a method with a route on the actual controller, say: "api/country/something"...
When I perform the above request, my code gets executed & data gets returned.
But when I try call my route on the base controller. E.G: "api/country/code/123"
I get a 404 error.
Question
Any idea on how to implement generic routes whilst making use of attribute routing?
Specific Controller
[RoutePrefix("Country")]
public class CountryController : MasterDataControllerBase<Country, CountryDto>
{
public CountryController(
IGenericRepository<Country> repository,
IMappingService mapper,
ISecurityService security) : base(repository, mapper, security)
{
}
}
Base
public class MasterDataControllerBase<TEntity, TEntityDto> : ControllerBase
where TEntity : class, ICodedEntity, new()
where TEntityDto : class, new()
{
private readonly IMappingService mapper;
private readonly IGenericRepository<TEntity> repository;
private readonly ISecurityService security;
public MasterDataControllerBase(IGenericRepository<TEntity> repository, IMappingService mapper, ISecurityService security)
{
this.security = security;
this.mapper = mapper;
this.repository = repository;
}
[Route("code/{code}")]
public TEntityDto Get(string code)
{
this.security.Enforce(AccessRight.CanAccessMasterData);
var result = this.repository.FindOne(o => o.Code == code);
return this.mapper.Map<TEntity, TEntityDto>(result);
}
}
Attribute routing in Web API doesn't support inheritance of the Route
attribute. You can see this indicated by Inherited = false
if you view the definition of the RouteAttribute
class...
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public sealed class RouteAttribute : Attribute, IDirectRouteFactory, IHttpRouteInfoProvider
{ ...
This explains why you're getting the 404, as the Route
attribute effectively disappears.
Since the attribute is not inheritable and the class is sealed, I don't know if there's a way to do this with the attribute routing infrastructure that comes out of the box.
Update: A member of the Web API team explains it was a design decision that it's not inherited... https://stackoverflow.com/a/19989344/3199781