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

后端 未结 4 1660
耶瑟儿~
耶瑟儿~ 2020-12-25 09:10

In previous asp.net web api, I implement DefaultHttpControllerSelector to specify how I want the request to locate my controller. I often have diff

相关标签:
4条回答
  • 2020-12-25 09:29

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

    https://github.com/GoAheadTours/NamespaceVersioning

    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) {
                continue;
            }
            var nameSpace = controller.ControllerType.Namespace.Split('.');
            var version = nameSpace.FirstOrDefault(x => Regex.IsMatch(x, @"[v][\d*]"));
            if (string.IsNullOrEmpty(version)) {
                continue;
            }
            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

    0 讨论(0)
  • 2020-12-25 09:38

    Use the routing attributes to control versions.

    i.e.

    [Route("api/v1/[controller]")]
    public class BookingV1Controller : Controller
    {
      ....
    }
    
    [Route("api/v2/[controller]")]
    public class BookingV2Controller : Controller
    {
      ....
    }
    

    For more information relating to migrating from standard Web Api and .NET Core ASP.NET have a look at: MSDN: Migrating from ASP.NET Web Api

    0 讨论(0)
  • 2020-12-25 09:38

    For that Add service API versioning to your ASP.NET Core applications

      public void ConfigureServices( IServiceCollection services )
        {
            services.AddMvc();
            services.AddApiVersioning();
    
            // remaining other stuff omitted for brevity
        }
    

    QUERYSTRING PARAMETER VERSIONING

    [ApiVersion( "2.0" )]
    [Route( "api/helloworld" )]
    public class HelloWorld2Controller : Controller {
        [HttpGet]
        public string Get() => "Hello world!";
    }
    

    So this means to get 2.0 over 1.0 in another Controller with the same route, you'd go here:

    /api/helloworld?api-version=2.0

    we can have the same controller name with different namespaces

    URL PATH SEGMENT VERSIONING

     [ApiVersion( "1.0" )]
     [Route( "api/v{version:apiVersion}/[controller]" )]
     public class HelloWorldController : Controller {
        public string Get() => "Hello world!";
     }
    [ApiVersion( "2.0" )]
    [ApiVersion( "3.0" )]
    [Route( "api/v{version:apiVersion}/helloworld" )]
    public class HelloWorld2Controller : Controller {
        [HttpGet]
        public string Get() => "Hello world v2!";
    
        [HttpGet, MapToApiVersion( "3.0" )]
        public string GetV3() => "Hello world v3!";
    }
    

    Header Versioning

      public void ConfigureServices( IServiceCollection services )
        {
            services.AddMvc();
            services.AddApiVersioning(o => o.ApiVersionReader = new HeaderApiVersionReader("api-version"));
        }
    

    When you do HeaderApiVersioning you won't be able to just do a GET in your browser, so I'll use Postman to add the header (or I could use Curl, or WGet, or PowerShell, or a Unit Test):

    Image

    please refer https://www.hanselman.com/blog/ASPNETCoreRESTfulWebAPIVersioningMadeEasy.aspx

    0 讨论(0)
  • 2020-12-25 09:44

    This is a very old question that I stumbled upon, but there are much better solutions now. There is this package

    Microsoft.AspNetCore.Mvc.Versioning

    Which has a much more feature rich way of implementing versioning controls. These include being able to use URL query strings, url paths, headers, or custom version readers. Being able to read the version from HTTPContext etc.

    In short, you add the following into your ConfigureServices method in startup.cs

    services.AddApiVersioning(o => {
        o.ReportApiVersions = true;
        o.AssumeDefaultVersionWhenUnspecified = true;
                o.DefaultApiVersion = new ApiVersion(1, 0);
    });
    

    Then you have to decorate your controllers with an ApiVersion.

    [ApiVersion("1.0")]
    [Route("api/home")]
    public class HomeV1Controller : Controller
    {
        [HttpGet]
        public string Get() => "Version 1";
    }
    
    [ApiVersion("2.0")]
    [Route("api/home")]
    public class HomeV2Controller : Controller
    {
        [HttpGet]
        public string Get() => "Version 2";
    }
    

    You can also implement it in the path by putting it in the route.

    [ApiVersion("1.0")]
    [Route("api/{version:apiVersion}/home")]
    public class HomeV1Controller : Controller
    {
        [HttpGet]
        public string Get() => "Version 1";
    }
    
    [ApiVersion("2.0")]
    [Route("api/{version:apiVersion}/home")]
    public class HomeV2Controller : Controller
    {
        [HttpGet]
        public string Get() => "Version 2";
    }
    

    When you go down this method of actually having it implemented via the Microsoft package, it also means that you are able to deprecate versions, have version discovery, access the version number from the HttpContext easily etc. None of which you could really do if it's just hardcoded in your route.

    For more info (Including using it in a header) :

    • http://dotnetcoretutorials.com/2017/01/17/api-versioning-asp-net-core/

    • http://www.hanselman.com/blog/ASPNETCoreRESTfulWebAPIVersioningMadeEasy.aspx

    • https://github.com/Microsoft/aspnet-api-versioning/wiki

    0 讨论(0)
提交回复
热议问题