I have few controllers that inherit from the same base class. Among the different actions that they don’t share with each other, they do have a few that are completely identical. I would like to have these on my base class because they all work completely the same it’s just that they’re accessed through different routes.
How should I define these actions with several different routes?
My inherited classes also have a RoutePrefixAttribute set on them so each of them is pointing to a different route.
Example
I have base abstract class called Vehicle and then inherited Car, Bike, Bus etc. All of them would have common action Move()
/bus/move /car/move /bike/move
How can I define action Move() on my base class Vehicle so that it will be executed on each subclass route?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Check the answer I gave here WebApi2 attribute routing inherited controllers, which references the answer from this post .NET WebAPI Attribute Routing and inheritance.
What you need to do is overwrite the DefaultDirectRouteProvider:
public class WebApiCustomDirectRouteProvider : DefaultDirectRouteProvider {
protected override IReadOnlyList<IDirectRouteFactory>
GetActionRouteFactories(HttpActionDescriptor actionDescriptor) {
// inherit route attributes decorated on base class controller's actions
return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(inherit: true);
}
}
With that done you then need to configure it in your web API configuration:
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
.....
// Attribute routing (with inheritance).
config.MapHttpAttributeRoutes(new WebApiCustomDirectRouteProvider());
....
}
}
You will then be able to do what you described like this:
public abstract class VehicleControllerBase : ApiController {
[Route("move")] // All inheriting classes will now have a `{controller}/move` route
public virtual HttpResponseMessage Move() {
...
}
}
[RoutePrefix("car")] // will have a `car/move` route
public class CarController : VehicleControllerBase {
public virtual HttpResponseMessage CarSpecificAction() {
...
}
}
[RoutePrefix("bike")] // will have a `bike/move` route
public class BikeController : VehicleControllerBase {
public virtual HttpResponseMessage BikeSpecificAction() {
...
}
}
[RoutePrefix("bus")] // will have a `bus/move` route
public class BusController : VehicleControllerBase {
public virtual HttpResponseMessage BusSpecificAction() {
...
}
}
Method 2
This is what I did and it worked the way you mentioned in your question.
I created base ApiController class and inherited all my API controllers from it. I defined Delete operation in my Base class (which returns string “Not Supported”) and didn’t define delete on any of my child controller. Now when I do a delete on any of my controller I get the message “Not Supported” i.e. Base class’s delete is called. ( I am doing Delete request on Child, and not on base i.e. /Bike/move)
But if I define a Delete on any of the controller it gives me warning of Hiding base implementation, but on doing Delete request for api I get – "An error has occurred."
I haven’t tried doing RoutePrefix way.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0