Shittu Joseph Olugbenga Shittu Joseph Olugbenga - 1 year ago 155
ASP.NET (C#) Question

How can versioning be done in ASP.NET Core Web Api

In previous web api
, I implement
to specify how I want the request to locate my controller. I often have different controllers with different names but intended for same processes. The only difference is that one is of higher version than the other.

For example, I could have a controller named
, which would be meant to handle the version one of the service. I would also have
, which was designed to handle the version two of the service. A client application would then make a request to the service with this url
. To handle the request, I would provide a custom implementation of
to select the appropriate version of the controller required based on the requested version.

However, I seems not to have a way to do this in
. I have searched everywhere to no avail. No documentation that could help either.

I would appreciate if anyone can be of help to me here. Thanks.

I would also like to know what to do if the version is specified in a custom header. E.g


The requirement was that the version of the service should not be exposed in the URL. If no version is present, the service returns with instruction on how to add the version. If a requested controller is not present in the version requested, the system searches through the lower versions. If it finds it in any lower versions, it uses that. The reason for this is to prevent repetition of controllers on all versions. But with ASP.NET Core, this might not be possible.

Answer Source

I created a package for this purpose exactly after banging my head on this problem for a few days. It doesn't require attributes.

In summary, you can register an IApplicationModelConvention in your startup file that can iterate through controllers and register routes based on the namespaces. I created a v1 folder, and put my controller inside

The class that implements IApplicationModelConvention implements an Apply method with an ApplicationModel parameter that will have access to the Controllers in your app and their existing routes. If I see a controller does not have a route set up in my class I get the version from the namespace and use a pre-defined URL prefix to generate a route for that version.

public void Apply(ApplicationModel application) {
    foreach (var controller in application.Controllers) {
        var hasRouteAttribute = controller.Selectors.Any(x => x.AttributeRouteModel != null);
        if (hasRouteAttribute) {
        var nameSpace = controller.ControllerType.Namespace.Split('.');
        var version = nameSpace.FirstOrDefault(x => Regex.IsMatch(x, @"[v][\d*]"));
        if (string.IsNullOrEmpty(version)) {
        controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel() {
            Template = string.Format(urlTemplate, apiPrefix, version, controller.ControllerName)

I have all the code up on github and a link to the package on nuget as well

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download