예제 #1
0
 private static void ConfigureApiVersioningOptions(ApiVersioningOptions options)
 {
     options.AssumeDefaultVersionWhenUnspecified = false;
     options.ReportApiVersions = true;
     options.ApiVersionReader  = new HeaderApiVersionReader(ApiVersionHeaderName);
     options.ErrorResponses    = new ApiVersioningErrorResponseProvider();
 }
예제 #2
0
        /// <summary>
        /// Adds service API versioning to the specified services collection.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection">services</see> available in the application.</param>
        /// <param name="setupAction">An <see cref="Action{T}">action</see> used to configure the provided options.</param>
        /// <returns>The original <paramref name="services"/> object.</returns>
        public static IServiceCollection AddApiVersioning(this IServiceCollection services, Action <ApiVersioningOptions> setupAction)
        {
            Arg.NotNull(services, nameof(services));
            Contract.Ensures(Contract.Result <IServiceCollection>() != null);

            var options = new ApiVersioningOptions();

            setupAction(options);
            services.Add(new ServiceDescriptor(typeof(IApiVersionReader), options.ApiVersionReader));
            services.Add(new ServiceDescriptor(typeof(IApiVersionSelector), options.ApiVersionSelector));
            services.Add(new ServiceDescriptor(typeof(IErrorResponseProvider), options.ErrorResponses));
            services.Add(Singleton <IOptions <ApiVersioningOptions> >(new OptionsWrapper <ApiVersioningOptions>(options)));
            services.Replace(Singleton <IActionSelector, ApiVersionActionSelector>());
            services.TryAddSingleton <IApiVersionRoutePolicy, DefaultApiVersionRoutePolicy>();
            services.TryAddSingleton <ReportApiVersionsAttribute>();
            services.AddTransient <IStartupFilter, InjectApiVersionRoutePolicy>();
            services.AddMvcCore(mvcOptions => AddMvcOptions(mvcOptions, options));
            services.AddRouting(routeOptions => routeOptions.ConstraintMap.Add("apiVersion", typeof(ApiVersionRouteConstraint)));

            if (options.ReportApiVersions)
            {
                services.TryAddSingleton <IReportApiVersions, DefaultApiVersionReporter>();
            }
            else
            {
                services.TryAddSingleton <IReportApiVersions, DoNotReportApiVersions>();
            }

            return(services);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ApiVersionControllerSelector"/> class.
 /// </summary>
 /// <param name="configuration">The <see cref="HttpConfiguration">configuration</see> to initialize
 /// the controller selector with.</param>
 /// <param name="options">The <see cref="ApiVersioningOptions">service versioning options</see>
 /// associated with the controller selector.</param>
 public ApiVersionControllerSelector(HttpConfiguration configuration, ApiVersioningOptions options)
 {
     this.configuration  = configuration;
     this.options        = options;
     controllerInfoCache = new Lazy <ConcurrentDictionary <string, HttpControllerDescriptorGroup> >(InitializeControllerInfoCache);
     controllerTypeCache = new HttpControllerTypeCache(this.configuration);
 }
 protected override void OnAddApiVersioning(ApiVersioningOptions options)
 {
     options.ApiVersionReader = new MediaTypeApiVersionReader();
     options.AssumeDefaultVersionWhenUnspecified = true;
     options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
     options.ReportApiVersions  = true;
 }
예제 #5
0
        /// <summary>
        /// Adds service API versioning to the specified services collection.
        /// </summary>
        /// <param name="configuration">The <see cref="HttpConfiguration">configuration</see> that will use use service versioning.</param>
        /// <param name="setupAction">An <see cref="Action{T}">action</see> used to configure the provided options.</param>
        public static void AddApiVersioning(this HttpConfiguration configuration, Action <ApiVersioningOptions> setupAction)
        {
            Arg.NotNull(configuration, nameof(configuration));
            Arg.NotNull(setupAction, nameof(setupAction));

            var options  = new ApiVersioningOptions();
            var services = configuration.Services;

            setupAction(options);
            services.Replace(typeof(IHttpControllerSelector), new ApiVersionControllerSelector(configuration, options));
            services.Replace(typeof(IHttpActionSelector), new ApiVersionActionSelector());

            if (options.ReportApiVersions)
            {
                configuration.Filters.Add(new ReportApiVersionsAttribute());
            }

            if (options.ApiVersionReader.VersionsByMediaType())
            {
                configuration.Filters.Add(new ApplyContentTypeVersionActionFilter(options.ApiVersionReader));
            }

            configuration.Properties.AddOrUpdate(ApiVersioningOptionsKey, options, (key, oldValue) => options);
            configuration.ParameterBindingRules.Add(typeof(ApiVersion), ApiVersionParameterBinding.Create);
        }
        static void AddApiVersionConstraintIfNecessary(ODataRoute route, ApiVersioningOptions options)
        {
            Contract.Requires(route != null);
            Contract.Requires(options != null);

            var routePrefix          = route.RoutePrefix;
            var apiVersionConstraint = "{" + options.RouteConstraintName + "}";

            if (routePrefix == null || routePrefix.IndexOf(apiVersionConstraint, Ordinal) < 0 || route.Constraints.ContainsKey(options.RouteConstraintName))
            {
                return;
            }

            // note: even though the constraints are a dictionary, it's important to rebuild the entire collection
            // to make sure the api version constraint is evaluated first; otherwise, the current api version will
            // not be resolved when the odata versioning constraint is evaluated
            var originalConstraints = new Dictionary <string, object>(route.Constraints);

            route.Constraints.Clear();
            route.Constraints.Add(options.RouteConstraintName, new ApiVersionRouteConstraint());

            foreach (var constraint in originalConstraints)
            {
                route.Constraints.Add(constraint.Key, constraint.Value);
            }
        }
예제 #7
0
        /// <summary>
        /// Adds service API versioning to the specified services collection.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection">services</see> available in the application.</param>
        /// <param name="setupAction">An <see cref="Action{T}">action</see> used to configure the provided options.</param>
        /// <returns>The original <paramref name="services"/> object.</returns>
        public static IServiceCollection AddApiVersioning(this IServiceCollection services, Action <ApiVersioningOptions> setupAction)
        {
            Arg.NotNull(services, nameof(services));
            Contract.Ensures(Contract.Result <IServiceCollection>() != null);

            var options = new ApiVersioningOptions();

            setupAction(options);
            services.Add(new ServiceDescriptor(typeof(IApiVersionReader), options.ApiVersionReader));
            services.Add(new ServiceDescriptor(typeof(IApiVersionSelector), options.ApiVersionSelector));
            services.Add(Singleton <IOptions <ApiVersioningOptions> >(new OptionsWrapper <ApiVersioningOptions>(options)));
            services.Replace(Singleton <IActionSelector, ApiVersionActionSelector>());

            if (options.ReportApiVersions)
            {
                services.AddSingleton <ReportApiVersionsAttribute>();
            }

            services.AddMvcCore(
                mvcOptions =>
            {
                if (options.ReportApiVersions)
                {
                    mvcOptions.Filters.Add(typeof(ReportApiVersionsAttribute));
                }

                mvcOptions.Conventions.Add(new ApiVersionConvention(options.DefaultApiVersion, options.Conventions));
            });

            services.AddRouting(mvcOptions => mvcOptions.ConstraintMap.Add("apiVersion", typeof(ApiVersionRouteConstraint)));

            return(services);
        }
        public void get_edm_models_should_split_models_between_routes()
        {
            // arrange
            var configuration          = new HttpConfiguration();
            var controllerTypeResolver = new Mock <IHttpControllerTypeResolver>();
            var controllerTypes        = new List <Type>()
            {
                typeof(TestController), typeof(OtherTestController)
            };
            var options = new ApiVersioningOptions();

            controllerTypeResolver.Setup(ctr => ctr.GetControllerTypes(It.IsAny <IAssembliesResolver>())).Returns(controllerTypes);
            configuration.Services.Replace(typeof(IHttpControllerTypeResolver), controllerTypeResolver.Object);
            configuration.Services.Replace(typeof(IHttpControllerSelector), new ApiVersionControllerSelector(configuration, options));

            var defaultConfiguration = new Mock <Action <ODataModelBuilder, ApiVersion, string> >();
            var modelCreated         = new Mock <Action <ODataModelBuilder, IEdmModel> >();
            var builder = new VersionedODataModelBuilder(configuration)
            {
                DefaultModelConfiguration = (builder, version, prefix) =>
                {
                    if (prefix == "api2")
                    {
                        builder.EntitySet <TestEntity>("Tests");
                    }
                },
            };

            // act
            var models = builder.GetEdmModels("api2");

            // assert
            models.Should().HaveCount(2);
            models.ElementAt(1).FindDeclaredEntitySet("Tests").Should().NotBeNull();
        }
예제 #9
0
 private static void ConfigureApiVersioning(ApiVersioningOptions options)
 {
     options.ReportApiVersions = true;
     options.AssumeDefaultVersionWhenUnspecified = true;
     options.ApiVersionReader   = new ApiRequestVersionReader();
     options.ApiVersionSelector = new LatestApiVersionSelector();
 }
예제 #10
0
 protected override void OnAddApiVersioning(ApiVersioningOptions options)
 {
     options.ReportApiVersions = true;
     options.AssumeDefaultVersionWhenUnspecified = true;
     options.ApiVersionReader = ApiVersionReader.Combine(
         new QueryStringApiVersionReader(),
         new HeaderApiVersionReader("api-version", "x-ms-version"));
 }
예제 #11
0
 public static void SetVersion(this ApiVersioningOptions options)
 {
     options.AssumeDefaultVersionWhenUnspecified = true;
     options.DefaultApiVersion = new ApiVersion(1, 0);
     options.ReportApiVersions = true;
     //setupAction.ApiVersionReader = new HeaderApiVersionReader("api-version");
     //setupAction.ApiVersionReader = new MediaTypeApiVersionReader();
 }
예제 #12
0
 protected override void OnAddApiVersioning(ApiVersioningOptions options)
 {
     options.ReportApiVersions = true;
     options.Conventions.Controller <ValuesController>().HasApiVersion(1, 0);
     options.Conventions.Controller <Values2Controller>()
     .HasApiVersion(2, 0)
     .HasApiVersion(3, 0)
     .Action(c => c.GetV3()).MapToApiVersion(3, 0)
     .Action(c => c.GetV3(default)).MapToApiVersion(3, 0);
예제 #13
0
 private void GetApiVersioningOptions(ApiVersioningOptions apiVersioningOptions)
 {
     apiVersioningOptions.AssumeDefaultVersionWhenUnspecified = true;
     apiVersioningOptions.ReportApiVersions = true;
     apiVersioningOptions.DefaultApiVersion = new ApiVersion(1, 0);
     apiVersioningOptions.ApiVersionReader  = ApiVersionReader.Combine(new QueryStringApiVersionReader(),
                                                                       new HeaderApiVersionReader("X-Version"),
                                                                       new UrlSegmentApiVersionReader());
 }
예제 #14
0
        public static void ApplyDefaultVersioning(ApiVersioningOptions options)
        {
            options.ReportApiVersions = true;
            options.AssumeDefaultVersionWhenUnspecified = true;
            options.DefaultApiVersion = new ApiVersion(1, 0);
            options.UseApiBehavior    = false;

            options.Conventions.Add(new VersionByNamespaceConvention());
        }
 protected override void OnAddApiVersioning(ApiVersioningOptions options)
 {
     options.ReportApiVersions = true;
     options.Conventions.Controller <OrdersController>()
     .HasApiVersion(1, 0);
     options.Conventions.Controller <PeopleController>()
     .HasApiVersion(1, 0)
     .HasApiVersion(2, 0)
     .Action(c => c.Patch(default, null, null)).MapToApiVersion(2, 0);
예제 #16
0
 private static void MyConventions(ApiVersioningOptions config)
 {
     config.Conventions.Controller <ConventionController>()
     .HasDeprecatedApiVersion(new ApiVersion(1, 0))
     .HasApiVersion(new ApiVersion(1, 1))
     .Action(typeof(ConventionController).GetMethod("Get"))
     .MapToApiVersion(new ApiVersion(1, 0))
     .Action(typeof(ConventionController).GetMethod("GetWithGender"))
     .MapToApiVersion(new ApiVersion(1, 1));
 }
        static void AddMvcOptions(MvcOptions mvcOptions, ApiVersioningOptions options)
        {
            Contract.Requires(mvcOptions != null);
            Contract.Requires(options != null);

            if (options.ReportApiVersions)
            {
                mvcOptions.Filters.Add(new ReportApiVersionsAttribute());
            }

            mvcOptions.Conventions.Add(new ApiVersionConvention(options.DefaultApiVersion, options.Conventions));
        }
        public void get_controller_name_should_return_expected_value(HttpRequestMessage request, string expected)
        {
            // arrange
            var configuration = new HttpConfiguration();
            var options       = new ApiVersioningOptions();
            var selector      = new ApiVersionControllerSelector(configuration, options);

            // act
            var controllerName = selector.GetControllerName(request);

            // assert
            controllerName.Should().Be(expected);
        }
        public void get_controller_mapping_should_return_expected_result()
        {
            // arrange
            var configuration = new HttpConfiguration();
            var options       = new ApiVersioningOptions();
            var selector      = new ApiVersionControllerSelector(configuration, options);

            // act
            var mapping = selector.GetControllerMapping();

            // assert
            mapping.Values.Cast <HttpControllerDescriptorGroup>().Should().NotBeEmpty();
        }
예제 #20
0
 public static void ConfigureAbp(this ApiVersioningOptions options, AbpAspNetCoreMvcOptions mvcOptions)
 {
     foreach (var setting in mvcOptions.ConventionalControllers.ConventionalControllerSettings)
     {
         if (setting.ApiVersionConfigurer == null)
         {
             ConfigureApiVersionsByConvention(options, setting);
         }
         else
         {
             setting.ApiVersionConfigurer.Invoke(options);
         }
     }
 }
 protected override void OnAddApiVersioning(ApiVersioningOptions options)
 {
     options.ReportApiVersions = true;
     options.Conventions.Controller <ValuesController>().HasApiVersion(1, 0);
     options.Conventions.Controller <Values2Controller>()
     .HasApiVersion(2, 0)
     .HasApiVersion(3, 0)
     .Action(c => c.GetV3()).MapToApiVersion(3, 0)
     .Action(c => c.GetV3(default(int))).MapToApiVersion(3, 0);
     options.Conventions.Controller <HelloWorldController>().HasDeprecatedApiVersion(1, 0);
     options.Conventions.Controller <HelloWorld2Controller>()
     .HasApiVersion(2, 0)
     .HasApiVersion(3, 0)
     .AdvertisesApiVersion(4, 0)
     .Action(c => c.GetV3()).MapToApiVersion(3, 0)
     .Action(c => c.GetV3(default(int))).MapToApiVersion(3, 0);
 }
예제 #22
0
        public static void AddApiVersioning(this HttpConfiguration configuration, Action <ApiVersioningOptions> setupAction)
        {
            Arg.NotNull(configuration, nameof(configuration));
            Arg.NotNull(setupAction, nameof(setupAction));

            var options  = new ApiVersioningOptions();
            var services = configuration.Services;

            setupAction(options);
            services.Replace(typeof(IHttpControllerSelector), new ApiVersionControllerSelector(configuration, options));
            services.Replace(typeof(IHttpActionSelector), new ApiVersionActionSelector());

            if (options.ReportApiVersions)
            {
                configuration.Filters.Add(new ReportApiVersionsAttribute());
            }

            configuration.Properties.AddOrUpdate(ApiVersioningOptionsKey, options, (key, oldValue) => options);
        }
예제 #23
0
    private static void ConfigureApiVersionsByConvention(ApiVersioningOptions options, ConventionalControllerSetting setting)
    {
        foreach (var controllerType in setting.ControllerTypes)
        {
            var controllerBuilder = options.Conventions.Controller(controllerType);

            if (setting.ApiVersions.Any())
            {
                foreach (var apiVersion in setting.ApiVersions)
                {
                    controllerBuilder.HasApiVersion(apiVersion);
                }
            }
            else
            {
                if (!controllerType.IsDefined(typeof(ApiVersionAttribute), true))
                {
                    controllerBuilder.IsApiVersionNeutral();
                }
            }
        }
    }
예제 #24
0
        public static ApiVersioningOptions AddConventionsFromAssembly(this ApiVersioningOptions options)
        {
            var versionedControllers = from type in typeof(Startup).Assembly.GetTypes()
                                       where type.IsPublic && !type.IsAbstract &&
                                       typeof(ControllerBase).IsAssignableFrom(type) &&
                                       type.HasAttribute <ApiVersionAttribute>()
                                       select type;

            foreach (var classType in versionedControllers)
            {
                var apiVersionAttributes = classType.GetCustomAttributes <ApiVersionAttribute>();
                foreach (var apiVersionAttribute in apiVersionAttributes)
                {
                    foreach (var apiVersion in apiVersionAttribute.Versions)
                    {
                        options.Conventions
                        .Controller(classType)
                        .HasApiVersion(apiVersion);
                    }
                }
            }

            return(options);
        }
        public static void ConfigureAbp(this ApiVersioningOptions options, IServiceCollection services)
        {
            //TODO: Use new builder will be released with Api Versioning 2.1 instead of reflection!

            services.AddTransient <IRequestedApiVersion, HttpContextRequestedApiVersion>();

            services.Configure <AbpAspNetCoreMvcOptions>(op =>
            {
                //TODO: Configuring api version should be done directly inside ConfigureAbp,
                //TODO: not in a callback that will be called by MVC later! For that, we immediately need to controllerAssemblySettings

                foreach (var setting in op.ConventionalControllers.ConventionalControllerSettings)
                {
                    if (setting.ApiVersionConfigurer == null)
                    {
                        ConfigureApiVersionsByConvention(options, setting);
                    }
                    else
                    {
                        setting.ApiVersionConfigurer.Invoke(options);
                    }
                }
            });
        }
예제 #26
0
 protected override void OnAddApiVersioning(ApiVersioningOptions options) => options.ReportApiVersions = true;
 /// <summary>
 /// Initializes a new instance of the <see cref="LowestImplementedApiVersionSelector"/> class.
 /// </summary>
 /// <param name="options">The <see cref="ApiVersioningOptions">API versioning options</see> associated with the selector.</param>
 public LowestImplementedApiVersionSelector(ApiVersioningOptions options)
 {
     Arg.NotNull(options, nameof(options));
     this.options = options;
 }
 protected abstract void OnAddApiVersioning(ApiVersioningOptions options);
 protected ControllerSelector(ApiVersioningOptions options)
 {
     Contract.Requires(options != null);
     this.options = options;
 }
예제 #30
0
 protected override void OnAddApiVersioning(ApiVersioningOptions options)
 {
     options.ReportApiVersions = true;
     options.Conventions.Add(new VersionByNamespaceConvention());
 }