1

I want a base controller that has a shared minimum for all my controllers, and then inherit each controller from this base controller, extending with whatever actions the specific controller is supposed to handle.

[RoutePrefix("api/myapi/{apiVersion}/{id}")]
public abstract class BaseController : ApiController
{
}

[RoutePrefix("foo")]
public class FooController : BaseController
{
    // Supposed to have /api/myapi/{apiVersion}/{id}/foo base path

    public void Get(int id)
    {
        // Expected: /api/myapi/v1.0/"some id"/foo
        return Ok();
        // Result: /foo
    }
}


[RoutePrefix("bar")]
public class BarController : BaseController
{
    // Supposed to have /api/myapi/{apiVersion}/{id}/bar base path

    [Route("{action}", Name="BarAction")]
    public void Get(int id)
    {
        // Expected: /api/myapi/v1.0/"some id"/bar/"an action"
        return Ok();
        // Result: /bar/{action}
    }
}

So the idea is to have a base url like: http://hostname/api/myapi/v1.0/100 where 100 is just a random id.

Each controller that inherit from this base, should then extend the url, so FooController.cs should extend to GET http://hostname/api/myapi/v1.0/100/foo, while my BarController was expected to have http://hostname/api/myapi/v1.0/100/bar/"an action"

Since I'm using SwashBuckle to generate SwaggerUI for me, I have added a verion constraint into mig startup config:

Startup.cs:

var constraintResolver = new DefaultInlineConstraintResolver()
{
    ConstraintMap =
    {
        ["apiVersion"] = typeof(ApiVersionRouteConstraint)
    }
};
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes(constraintResolver);

I'm running Owin self host version 5.3.x / WebApi 2.2.

Can anyone please tell me if it is possible to use and extend atribute prefixes from a base class, and how?

grmihel
  • 784
  • 3
  • 15
  • 40
  • That is not how attribute routing works. You will need to place the full intended base path on their respective controllers. You cannot extend attribute prefixes. – Nkosi Sep 06 '17 at 11:23
  • There must be a better way to do this then, I mean if I out of sudden want to change my base route, I have to go through a LOT of controllers to make this change, since each of the controllers then will have the bae route defined on top? – grmihel Sep 06 '17 at 11:48
  • No what I meant was that you cant extend the base. You can still use it. but then that means that the derived controller's route would have to look something like `[Route("bar/{action}")]`. Using the route prefix on the derived controller would override the base prefix – Nkosi Sep 06 '17 at 11:51
  • Take a look at a previous answer I gave around this topic https://stackoverflow.com/questions/23343328/webapi-controller-inheritance-and-attribute-routing?rq=1 – Nkosi Sep 06 '17 at 11:58
  • You will also end up with possible route conflicts because of the base prefix. – Nkosi Sep 06 '17 at 12:02
  • Took a look on you previous answer, but what I want to achieve is kinda opposite, making a base url to use across all controllers (as if you were defining a MapHttpRoutes in your startup config). So you mean that the derrived controller should then have no route prefix on top, and instead "bar" should be added in front of each route prefixed defined on each method? Like this: https://pastebin.com/E83Tbv44 – grmihel Sep 06 '17 at 12:18
  • Yes I was suggesting that, but I am not totally confident that it wont cause route conflicts. You would have to test it to confirm. – Nkosi Sep 06 '17 at 12:25
  • That does not seems to work unfortunately. SwashBuckle makes it look like bar/{action} but without the base part that is in the base class. It looks like it is totally ignoring the base path in RoutePrefix of the abstract base class... – grmihel Sep 06 '17 at 13:08
  • Late to the party, but you could use a constant on each sub-class instead: `[RoutePrefix(Constants.API_PREFIX)]`. Yes, you will have to put this on every controller but if you decide to change the prefix later, you only need to change it in one place. – Luka Kralj Sep 22 '22 at 14:00

0 Answers0