I'd like to expose a company's api by two ways:
api.company.com (pure WebApi web site)
company.com/api (add WebApi to existing MVC5 company site)
So, I placed models/controllers in a separate assembly and reference it from both web sites.
Also, I use route attributes:
[RoutePrefix("products")]
public class ProductsController : ApiController
Now, the controller above can be accessed by:
api.company.com/products which is good
company.com/products which I'd like to change to company.com/api/products
Is there a way to keep using route attributes and setup MVC project so it adds "api" for all routes?
Annotates a controller with a route prefix that applies to all actions within the controller. As you can see, the description for Route mentions exposing the action(s), but RoutePrefix does not.
We can override the RoutePrefix on a method, using the tilde(~) sign. We can easily define parameterized templates in the attribute based routing. We can have parameters defined in-between the API request URLs.
Web API 2 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API. For example, you can easily create URIs that describe hierarchies of resources.
In IP-based computer networks, a routing prefix can be seen as the unvarying portion of an address shared by each client on a single subnet. For example, many home networks commonly assign IPv4 addresses within the range of 192.168. 1.0 to 192.168. 1.255.
So this is probably not the only way you could do it, but this is how I would do it:
Based on a setting in your web.config, prepend to the route or not.
public class CustomRoutePrefixAttribute : RoutePrefixAttribute
{
public CustomRoutePrefixAttribute(string prefix) : base(prefix)
{
}
public override string Prefix
{
get
{
if (Configuration.PrependApi)
{
return "api/" + base.Prefix;
}
return base.Prefix;
}
}
}
EDIT (The below option is no longer supported as of Web API 2.2)
Alternatively you could also specify more than one route prefix:
[RoutePrefix("api/products")]
[RoutePrefix("products")]
public class ProductsController : ApiController
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With