Hello ABP,
We are trying to implement API versioning with tiered project. We use URI versioning for realizing that. We have checked your test project for api versioning. Also we have checked https://github.com/abpframework/abp/issues/3315 issue. We are able to create two different versions of our API. I can see clearly on Swagger. We cannot see all APIs relevant with ABP's modules such as Identity, Permission Management. We added HttpApi modules in PreConfigureServices for seeing on swagger. . We inserted account admin and account public as an example.
First question is what we have done is best practice for seeing the controllers related with ABP?
After inserting api versioning logic, web module crashed.
Host and Identity project work with no problem. Exception message is below. Swagger configuration code:
private void ConfigureSwagger(ServiceConfigurationContext context, IConfiguration configuration)
{
Configure<AbpAspNetCoreMvcOptions>(options => { context.Services.ExecutePreConfiguredActions(options); });
context.Services.AddControllers();
context.Services.AddAbpApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
options.ApiVersionReader = new UrlSegmentApiVersionReader();
var mvcOptions = context.Services.ExecutePreConfiguredActions<AbpAspNetCoreMvcOptions>();
options.ConfigureAbp(mvcOptions);
});
context.Services.AddVersionedApiExplorer(options =>
{
// add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
// note: the specified format code will format the version as "'v'major[.minor][-status]"
options.GroupNameFormat = "'v'VVV";
// note: this option is only necessary when versioning by url segment. the SubstitutionFormat
// can also be used to control the format of the API version in route templates
options.SubstituteApiVersionInUrl = true;
});
context.Services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
context.Services.AddSwaggerGen(options =>
{
options.OperationFilter<SwaggerDefaultValues>();
options.DocumentFilter<CustomSwaggerFilter>();
options.DocInclusionPredicate((docName, description) =>
{
// Get api major version
var apiVersion = $"v{description.GetApiVersion().MajorVersion}";
if (!docName.Equals(apiVersion))
return false;
// Replace router parameter
var values = description.RelativePath
.Split('/')
.Select(v => v.Replace("v{version}", apiVersion));
description.RelativePath = string.Join("/", values);
return true;
});
options.CustomSchemaIds((type) => type.FullName);
options.SchemaFilter<AddEnumSchemaFilter>();
});
}
Hello controller code :
using System.Threading.Tasks;
using ApiVersioningTiered.Controllers;
using Microsoft.AspNetCore.Mvc;
namespace Volo.Abp.AspNetCore.Mvc.Versioning.App
{
[ApiVersion("1.0")]
[ApiVersion("2.0")]
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
public class HelloController : ApiVersioningTieredController
{
[HttpGet]
public Task<string> GetAsync()
{
return Task.FromResult($"Get");
}
[HttpPost]
[Route("Test")]
[MapToApiVersion("1.0")]
public Task<string> PostAsyncV1()
{
return PostAsync();
}
[HttpPost]
[MapToApiVersion("2.0")]
[Route("Test")]
public Task<string> PostAsyncV2()
{
return PostAsync();
}
private Task<string> PostAsync()
{
return Task.FromResult($"Post-{HttpContext.GetRequestedApiVersion().ToString()}");
}
}
}
Are there any suggestions about that?
- ABP Framework version: v4.2.2
- UI type: MVC
- DB provider: EF Core
- Tiered (MVC) or Identity Server Separated (Angular): yes
- Exception message and stack trace:
* AbpException: Could not found remote action for method: System.Threading.Tasks.Task`1[Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationConfigurationDto] GetAsync() on the URL: https://localhost:44321/
Volo.Abp.Http.Client.DynamicProxying.ApiDescriptionFinder.FindActionAsync(HttpClient client, string baseUrl, Type serviceType, MethodInfo method)
Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor<TService>.MakeRequestAsync(IAbpMethodInvocation invocation)
Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor<TService>.MakeRequestAndGetResultAsync<T>(IAbpMethodInvocation invocation)
Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor<TService>.GetResultAsync(Task task, Type resultType)
Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor<TService>.InterceptAsync(IAbpMethodInvocation invocation)
Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter<TInterceptor>.InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo)
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue<TResult>.ProceedAsync()
Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter<TInterceptor>.InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
Volo.Abp.AspNetCore.Mvc.Client.MvcCachedApplicationConfigurationClient.<GetAsync>b__14_0()
Volo.Abp.Caching.DistributedCache<TCacheItem, TCacheKey>.GetOrAddAsync(TCacheKey key, Func<Task<TCacheItem>> factory, Func<DistributedCacheEntryOptions> optionsFactory, Nullable<bool> hideErrors, bool considerUow, CancellationToken token)
Volo.Abp.AspNetCore.Mvc.Client.MvcCachedApplicationConfigurationClient.GetAsync()
Volo.Abp.AspNetCore.Mvc.Client.RemoteLanguageProvider.GetLanguagesAsync()
Microsoft.AspNetCore.RequestLocalization.DefaultAbpRequestLocalizationOptionsProvider.GetLocalizationOptionsAsync()
Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
8 Answer(s)
-
0
hi
Can you share your app source code wihe me?
liming.ma@volosoft.com
-
0
Hi,
I sent the source code
-
0
Hi, Can you change your
UseSwaggerUI
middleware as follows?app.UseSwaggerUI(options => { // builds a swagger endpoint for each API version foreach (var description in provider.ApiVersionDescriptions) { options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant()); } var configuration = context.GetConfiguration(); options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); });
-
0
Hi,
it is already like that
app.UseSwaggerUI(options => { options.DocumentTitle = "NMM API"; // Display latest api version by default // var provider = context.ServiceProvider.GetRequiredService<IApiVersionDescriptionProvider>(); foreach (var description in provider.ApiVersionDescriptions) { options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant()); } var configuration = context.GetConfiguration(); options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); options.OAuthClientSecret(configuration["AuthServer:SwaggerClientSecret"]); });
-
0
hi
I will check your project asap.
-
0
hi
Please remove the
options.ConventionalControllers.Create(typeof(AbpAccountAdminHttpApiModule).Assembly,...
You cannot change the API version in the module. You can only control your own API.
Add below to HttpApi.Host project.
context.Services.Configure<ApiVersioningOptions>(options => { options.UseApiBehavior = false; });
Add below to Web project.
context.Services.AddApiVersioning();
-
0
Hi,
Thank you.
-
0
Hi @uyarbtrlp, as I see your problem is resolved so I close the question. If your problem is not resolved yet, please don't hesitate to re-open it.