From 515bd63f1c160ca55329a4e6c14b2a6408599516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 5 Oct 2017 16:56:22 +0300 Subject: [PATCH] Send version for query string or path in C# client. --- .../Mvc/AbpControllerAssemblySetting.cs | 2 +- .../AspNetCoreApiDescriptionModelProvider.cs | 4 +- ...lectionDynamicHttpClientProxyExtensions.cs | 1 + .../Client/DynamicProxying/ApiVersionInfo.cs | 22 +++++++++++ .../DynamicHttpProxyInterceptor.cs | 33 +++++++++++++--- .../HttpActionParameterHelper.cs | 2 +- .../Http/Client/DynamicProxying/UrlBuilder.cs | 38 ++++++++++++------- .../Modeling/ActionApiDescriptionModel.cs | 13 ++++++- .../Modeling/ParameterApiDescriptionModel.cs | 2 +- .../Generic/AbpDictionaryExtensions.cs | 28 ++++++++++++++ ...Abp.AspNetCore.Mvc.Versioning.Tests.csproj | 3 -- .../AbpAspNetCoreMvcVersioningTestModule.cs | 28 ++++++++++++-- .../Versioning/App/Compat/ITodoAppService.cs | 9 +++++ .../Versioning/App/Compat/TodoAppService.cs | 24 ++++++++++++ .../Mvc/Versioning/App/HelloController.cs | 17 +++++++++ .../Mvc/Versioning/App/IHelloController.cs | 10 +++++ .../Test/Compat/TodoAppService_Tests.cs | 23 +++++++++++ .../Versioning/Test/HelloController_Tests.cs | 24 ++++++++++++ .../Versioning/Test/TodoAppService_Tests.cs | 2 +- 19 files changed, 254 insertions(+), 31 deletions(-) create mode 100644 src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiVersionInfo.cs create mode 100644 test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/Compat/ITodoAppService.cs create mode 100644 test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/Compat/TodoAppService.cs create mode 100644 test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/HelloController.cs create mode 100644 test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/IHelloController.cs create mode 100644 test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/Compat/TodoAppService_Tests.cs create mode 100644 test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/HelloController_Tests.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerAssemblySetting.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerAssemblySetting.cs index be40f2d95f..a86d5d920f 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerAssemblySetting.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpControllerAssemblySetting.cs @@ -43,7 +43,7 @@ namespace Volo.Abp.AspNetCore.Mvc [CanBeNull] public Func UrlActionNameNormalizer { get; set; } - public List ApiVersions { get; set; } + public List ApiVersions { get; } public Action ApiVersionConfigurer { get; set; } diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs index 594850d10c..53359745fd 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; @@ -80,7 +81,8 @@ namespace Volo.Abp.AspNetCore.Mvc var actionModel = controllerModel.AddAction(uniqueMethodName, ActionApiDescriptionModel.Create( method, apiDescription.RelativePath, - apiDescription.HttpMethod + apiDescription.HttpMethod, + setting?.ApiVersions.Select(v => v.ToString()).ToList() ?? new List() )); AddParameterDescriptionsToModel(actionModel, method, apiDescription); diff --git a/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs b/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs index c3ec5c76b5..d68d21ec3e 100644 --- a/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs +++ b/src/Volo.Abp.Http.Client/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicHttpClientProxyExtensions.cs @@ -15,6 +15,7 @@ namespace Microsoft.Extensions.DependencyInjection public static IServiceCollection AddHttpClientProxies(this IServiceCollection services, Assembly assembly, string remoteServiceName = RemoteServiceConfigurationDictionary.DefaultName) { + //TODO: Make a configuration option and add remoteServiceName inside it! //TODO: Add option to change type filter var serviceTypes = assembly.GetTypes().Where(t => diff --git a/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiVersionInfo.cs b/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiVersionInfo.cs new file mode 100644 index 0000000000..f4239ad89f --- /dev/null +++ b/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiVersionInfo.cs @@ -0,0 +1,22 @@ +using System; + +namespace Volo.Abp.Http.Client.DynamicProxying +{ + internal class ApiVersionInfo + { + public string BindingSource { get; } + public string Version { get; } + + public ApiVersionInfo(string bindingSource, string version) + { + BindingSource = bindingSource; + Version = version; + } + + public bool ShouldSendInQueryString() + { + //TODO: Constant! TODO: Other sources! + return !BindingSource.IsIn("Path"); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs index 81b88f59f4..d9bcdcc67d 100644 --- a/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs +++ b/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs @@ -57,7 +57,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying else { var responseAsString = AsyncHelper.RunSync(() => MakeRequest(invocation)); - + //TODO: Think on that if (TypeHelper.IsPrimitiveExtendedIncludingNullable(invocation.Method.ReturnType, true)) { @@ -105,10 +105,9 @@ namespace Volo.Abp.Http.Client.DynamicProxying using (var client = _httpClientFactory.Create()) { var baseUrl = GetBaseUrl(); - var version = GetVersion(); //TODO: Add version to the request (querystring, media type, path value or custom header!) - var action = await _apiDescriptionFinder.FindActionAsync(baseUrl, typeof(TService), invocation.Method); - var url = baseUrl + UrlBuilder.GenerateUrlWithParameters(action, invocation.ArgumentsDictionary); + var apiVersion = GetApiVersionInfo(action); + var url = baseUrl + UrlBuilder.GenerateUrlWithParameters(action, invocation.ArgumentsDictionary, apiVersion); var requestMessage = new HttpRequestMessage(action.GetHttpMethod(), url) { @@ -128,6 +127,30 @@ namespace Volo.Abp.Http.Client.DynamicProxying } } + private ApiVersionInfo GetApiVersionInfo(ActionApiDescriptionModel action) + { + var apiVersion = FindBestApiVersion(action); + var versionParam = action.Parameters.FirstOrDefault(p => p.Name == "apiVersion"); + return new ApiVersionInfo(versionParam?.BindingSourceId, apiVersion); + } + + private string FindBestApiVersion(ActionApiDescriptionModel action) + { + var configuredVersion = GetConfiguredApiVersion(); + + if (action.SupportedVersions.IsNullOrEmpty()) + { + return configuredVersion ?? "1.0"; + } + + if (action.SupportedVersions.Contains(configuredVersion)) + { + return configuredVersion; + } + + return action.SupportedVersions.Last(); //TODO: Ensure to get the latest version! + } + private static void AddHeaders(IAbpMethodInvocation invocation, ActionApiDescriptionModel action, HttpRequestMessage requestMessage) { foreach (var headerParameter in action.Parameters.Where(p => p.BindingSourceId == ParameterBindingSources.Header)) @@ -150,7 +173,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying ?? throw new AbpException($"Could not find Base URL for {typeof(TService).FullName}."); } - private string GetVersion() + private string GetConfiguredApiVersion() { var clientConfig = _clientOptions.HttpClientProxies.GetOrDefault(typeof(TService)) ?? throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {typeof(TService).FullName}."); diff --git a/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/HttpActionParameterHelper.cs b/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/HttpActionParameterHelper.cs index 5eb5eba1de..36c3171dc2 100644 --- a/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/HttpActionParameterHelper.cs +++ b/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/HttpActionParameterHelper.cs @@ -8,7 +8,7 @@ namespace Volo.Abp.Http.Client.DynamicProxying { public static object FindParameterValue(IReadOnlyDictionary methodArguments, ParameterApiDescriptionModel apiParameter) { - var value = methodArguments[apiParameter.NameOnMethod]; + var value = methodArguments.GetOrDefault(apiParameter.NameOnMethod); if (value == null) { return null; diff --git a/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/UrlBuilder.cs b/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/UrlBuilder.cs index f829c9a7a7..6a1575c24e 100644 --- a/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/UrlBuilder.cs +++ b/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/UrlBuilder.cs @@ -9,17 +9,17 @@ namespace Volo.Abp.Http.Client.DynamicProxying { internal static class UrlBuilder { - public static string GenerateUrlWithParameters(ActionApiDescriptionModel action, IReadOnlyDictionary methodArguments) + public static string GenerateUrlWithParameters(ActionApiDescriptionModel action, IReadOnlyDictionary methodArguments, ApiVersionInfo apiVersion) { var urlBuilder = new StringBuilder(action.Url); - ReplacePathVariables(urlBuilder, action.Parameters, methodArguments); - AddQueryStringParameters(urlBuilder, action.Parameters, methodArguments); + ReplacePathVariables(urlBuilder, action.Parameters, methodArguments, apiVersion); + AddQueryStringParameters(urlBuilder, action.Parameters, methodArguments, apiVersion); return urlBuilder.ToString(); } - private static void ReplacePathVariables(StringBuilder urlBuilder, IList actionParameters, IReadOnlyDictionary methodArguments) + private static void ReplacePathVariables(StringBuilder urlBuilder, IList actionParameters, IReadOnlyDictionary methodArguments, ApiVersionInfo apiVersion) { var pathParameters = actionParameters .Where(p => p.BindingSourceId == ParameterBindingSources.Path) @@ -30,9 +30,15 @@ namespace Volo.Abp.Http.Client.DynamicProxying return; } - foreach (var pathParameter in pathParameters) + if (pathParameters.Any(p => p.Name == "apiVersion")) + { + urlBuilder = urlBuilder.Replace("{apiVersion}", apiVersion.Version); + } + + foreach (var pathParameter in pathParameters.Where(p => p.Name != "apiVersion")) //TODO: Constant! { var value = HttpActionParameterHelper.FindParameterValue(methodArguments, pathParameter); + if (value == null) { if (pathParameter.IsOptional) @@ -55,18 +61,14 @@ namespace Volo.Abp.Http.Client.DynamicProxying } } - private static void AddQueryStringParameters(StringBuilder urlBuilder, IList actionParameters, IReadOnlyDictionary methodArguments) + private static void AddQueryStringParameters(StringBuilder urlBuilder, IList actionParameters, IReadOnlyDictionary methodArguments, ApiVersionInfo apiVersion) { var queryStringParameters = actionParameters .Where(p => p.BindingSourceId.IsIn(ParameterBindingSources.ModelBinding, ParameterBindingSources.Query)) .ToArray(); - if (!queryStringParameters.Any()) - { - return; - } - var isFirstParam = true; + foreach (var queryStringParameter in queryStringParameters) { var value = HttpActionParameterHelper.FindParameterValue(methodArguments, queryStringParameter); @@ -75,11 +77,21 @@ namespace Volo.Abp.Http.Client.DynamicProxying continue; } - urlBuilder.Append(isFirstParam ? "?" : "&"); - urlBuilder.Append(queryStringParameter.Name + "=" + System.Net.WebUtility.UrlEncode(value.ToString())); + AddQueryStringParameter(urlBuilder, isFirstParam, queryStringParameter.Name, value); isFirstParam = false; } + + if (apiVersion.ShouldSendInQueryString()) + { + AddQueryStringParameter(urlBuilder, isFirstParam, "apiVersion", apiVersion.Version); //TODO: Constant! + } + } + + private static void AddQueryStringParameter(StringBuilder urlBuilder, bool isFirstParam, string name, object value) + { + urlBuilder.Append(isFirstParam ? "?" : "&"); + urlBuilder.Append(name + "=" + System.Net.WebUtility.UrlEncode(value.ToString())); } } } diff --git a/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ActionApiDescriptionModel.cs b/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ActionApiDescriptionModel.cs index ffed6f2184..86d903f97f 100644 --- a/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ActionApiDescriptionModel.cs +++ b/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ActionApiDescriptionModel.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Reflection; +using JetBrains.Annotations; namespace Volo.Abp.Http.Modeling { @@ -15,6 +16,8 @@ namespace Volo.Abp.Http.Modeling public string Url { get; set; } + public IList SupportedVersions { get; set; } + public IList ParametersOnMethod { get; set; } public IList Parameters { get; set; } @@ -26,8 +29,13 @@ namespace Volo.Abp.Http.Modeling } - public static ActionApiDescriptionModel Create(MethodInfo method, string url, string httpMethod) + public static ActionApiDescriptionModel Create([NotNull] MethodInfo method, [NotNull] string url, [NotNull] string httpMethod, [NotNull] IList supportedVersions) { + Check.NotNull(method, nameof(method)); + Check.NotNull(url, nameof(url)); + Check.NotNull(httpMethod, nameof(httpMethod)); + Check.NotNull(supportedVersions, nameof(supportedVersions)); + return new ActionApiDescriptionModel { Name = method.Name, @@ -38,7 +46,8 @@ namespace Volo.Abp.Http.Modeling ParametersOnMethod = method .GetParameters() .Select(MethodParameterApiDescriptionModel.Create) - .ToList() + .ToList(), + SupportedVersions = supportedVersions }; } diff --git a/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ParameterApiDescriptionModel.cs b/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ParameterApiDescriptionModel.cs index 609fdd9000..d1de33258f 100644 --- a/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ParameterApiDescriptionModel.cs +++ b/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ParameterApiDescriptionModel.cs @@ -30,7 +30,7 @@ namespace Volo.Abp.Http.Modeling { Name = name, NameOnMethod = nameOnMethod, - TypeAsString = type.GetFullNameWithAssemblyName(), + TypeAsString = type?.GetFullNameWithAssemblyName(), IsOptional = isOptional, DefaultValue = defaultValue, ConstraintTypes = constraintTypes, diff --git a/src/Volo.Abp/System/Collections/Generic/AbpDictionaryExtensions.cs b/src/Volo.Abp/System/Collections/Generic/AbpDictionaryExtensions.cs index 47ceca79f2..bac4b58217 100644 --- a/src/Volo.Abp/System/Collections/Generic/AbpDictionaryExtensions.cs +++ b/src/Volo.Abp/System/Collections/Generic/AbpDictionaryExtensions.cs @@ -26,6 +26,20 @@ namespace System.Collections.Generic return false; } + /// + /// Gets a value from the dictionary with given key. Returns default value if can not find. + /// + /// Dictionary to check and get + /// Key to find the value + /// Type of the key + /// Type of the value + /// Value if found, default if can not found. + public static TValue GetOrDefault(this Dictionary dictionary, TKey key) + { + TValue obj; + return dictionary.TryGetValue(key, out obj) ? obj : default(TValue); + } + /// /// Gets a value from the dictionary with given key. Returns default value if can not find. /// @@ -40,6 +54,20 @@ namespace System.Collections.Generic return dictionary.TryGetValue(key, out obj) ? obj : default(TValue); } + /// + /// Gets a value from the dictionary with given key. Returns default value if can not find. + /// + /// Dictionary to check and get + /// Key to find the value + /// Type of the key + /// Type of the value + /// Value if found, default if can not found. + public static TValue GetOrDefault(this IReadOnlyDictionary dictionary, TKey key) + { + TValue obj; + return dictionary.TryGetValue(key, out obj) ? obj : default(TValue); + } + /// /// Gets a value from the dictionary with given key. Returns default value if can not find. /// diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj index 8253085d67..3db24955e1 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj @@ -35,9 +35,6 @@ PreserveNewest - - - diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs index bf899b8436..52860d2ad2 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs @@ -1,4 +1,6 @@ using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Versioning; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Modularity; using Volo.Abp.AspNetCore.Mvc.Versioning.App; @@ -23,15 +25,35 @@ namespace Volo.Abp.AspNetCore.Mvc.Versioning services.Configure(options => { + //2.0 Version options.AppServiceControllers.Create(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly, opts => { - + opts.TypePredicate = t => t.Namespace == typeof(Volo.Abp.AspNetCore.Mvc.Versioning.App.TodoAppService).Namespace; + opts.ApiVersions.Add(new ApiVersion(2, 0)); + }); + + //1.0 Compatability version + options.AppServiceControllers.Create(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly, opts => + { + opts.TypePredicate = t => t.Namespace == typeof(Volo.Abp.AspNetCore.Mvc.Versioning.App.Compat.TodoAppService).Namespace; + opts.ApiVersions.Add(new ApiVersion(1, 0)); + opts.RootPath = "app/compat"; }); }); - services.AddAssemblyOf(); + services.AddApiVersioning(options => + { + options.ReportApiVersions = true; + options.AssumeDefaultVersionWhenUnspecified = true; + + options.ApiVersionReader = new QueryStringApiVersionReader("apiVersion"); - services.AddHttpClientProxy(); + options.ConfigureAbp(services); + }); + + services.AddAssemblyOf(); + + services.AddHttpClientProxies(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly); services.Configure(options => { diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/Compat/ITodoAppService.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/Compat/ITodoAppService.cs new file mode 100644 index 0000000000..0a8ed290ce --- /dev/null +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/Compat/ITodoAppService.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Application.Services; + +namespace Volo.Abp.AspNetCore.Mvc.Versioning.App.Compat +{ + public interface ITodoAppService : IApplicationService + { + string Get(int id); + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/Compat/TodoAppService.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/Compat/TodoAppService.cs new file mode 100644 index 0000000000..83835fa9b0 --- /dev/null +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/Compat/TodoAppService.cs @@ -0,0 +1,24 @@ +using Volo.Abp.ApiVersioning; + +namespace Volo.Abp.AspNetCore.Mvc.Versioning.App.Compat +{ + public class TodoAppService : ITodoAppService + { + private readonly IRequestedApiVersion _requestedApiVersion; + + public TodoAppService(IRequestedApiVersion requestedApiVersion) + { + _requestedApiVersion = requestedApiVersion; + } + + public string Get(int id) + { + return "Compat-" + id + "-" + GetVersionOrNone(); + } + + private string GetVersionOrNone() + { + return _requestedApiVersion.Current ?? "NONE"; + } + } +} diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/HelloController.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/HelloController.cs new file mode 100644 index 0000000000..fb39ae53ed --- /dev/null +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/HelloController.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Volo.Abp.AspNetCore.Mvc.Versioning.App +{ + [ApiVersion("1.0")] + [ApiVersion("2.0")] + [Route("api/v{apiVersion:apiVersion}/[controller]")] + public class HelloController : AbpController, IHelloController + { + [HttpPost] + public Task PostAsync() + { + return Task.FromResult($"42-{HttpContext.GetRequestedApiVersion().ToString()}"); + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/IHelloController.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/IHelloController.cs new file mode 100644 index 0000000000..5f43027c8e --- /dev/null +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/App/IHelloController.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Volo.Abp.Application.Services; + +namespace Volo.Abp.AspNetCore.Mvc.Versioning.App +{ + public interface IHelloController : IRemoteService + { + Task PostAsync(); + } +} diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/Compat/TodoAppService_Tests.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/Compat/TodoAppService_Tests.cs new file mode 100644 index 0000000000..0ce095c470 --- /dev/null +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/Compat/TodoAppService_Tests.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.AspNetCore.Mvc.Versioning.App.Compat; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Versioning.Test.Compat +{ + public class TodoAppService_Tests : AspNetCoreMvcVersioningTestBase + { + private readonly ITodoAppService _todoAppService; + + public TodoAppService_Tests() + { + _todoAppService = ServiceProvider.GetRequiredService(); + } + + [Fact] + public void Get() + { + _todoAppService.Get(42).ShouldBe("Compat-42-1.0"); + } + } +} diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/HelloController_Tests.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/HelloController_Tests.cs new file mode 100644 index 0000000000..519bfffd11 --- /dev/null +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/HelloController_Tests.cs @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.AspNetCore.Mvc.Versioning.App; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.Versioning.Test +{ + public class HelloController_Tests: AspNetCoreMvcVersioningTestBase + { + private readonly IHelloController _todoAppService; + + public HelloController_Tests() + { + _todoAppService = ServiceProvider.GetRequiredService(); + } + + [Fact] + public async Task PostAsync() + { + (await _todoAppService.PostAsync()).ShouldBe("42-2.0"); + } + } +} diff --git a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/TodoAppService_Tests.cs b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/TodoAppService_Tests.cs index 66644b1a05..90ea5970b0 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/TodoAppService_Tests.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/Test/TodoAppService_Tests.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Versioning.Test [Fact] public void Get() { - _todoAppService.Get(42).ShouldBe("42-NONE"); + _todoAppService.Get(42).ShouldBe("42-2.0"); } } }