I have created a generic base API controller and inherited that in to multiple other controllers.
I think Swagger always need unique and not so ambiguous route name etc.
Now because of generic controller implementation, I am getting error like:
SwaggerGeneratorException: Conflicting method/path combination :Actions require a unique method/path combination for Swagger/OpenAPI 3.0. : Use ConflictingActionsResolver as a workaround"
Is there any way to resolve it?
[ApiController]
[Route("api/odata/[controller]/[action]")]
[Consumes("application/json")]
public class BaseController<T> : Controller where T : XPBaseObject
{
private Storage<T> _storage;
public BaseController(Storage<T> storage)
{
_storage = storage;
}
[Route("Get")]
[HttpGet]
public IEnumerable<T> Get()
{
return _storage.GetAll();
}
}
public class EmployeeController : BaseController<Employee>
{
public EmployeeController(Storage<Employee> storage) : base(storage)
{
}
}//Employee controller
public class CompanyController : BaseController<Company>
{
public CompanyController(Storage<Company> storage) : base(storage)
{
}
}//Company controller
//Startup.cs
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// This method gets called by the runtime.Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddOData(opt => opt.Count().Filter().Expand().Select().OrderBy().SetMaxTop(100));
services.AddControllers().AddOData(opt => opt.AddRouteComponents("api/odata", SingletonEdmModel.GetEdmModel()));
services.AddControllers(mvcOptions =>
{
mvcOptions.EnableEndpointRouting = false;
});
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<XpoDataStoreProviderService>();
services.AddSingleton(Configuration);
services.AddSingleton(typeof(Storage<>));
services.AddHttpContextAccessor();
services.AddScoped<SecurityProvider>();
services.AddRouting();
services.AddScoped((serviceProvider) => {
AuthenticationMixed authentication = new AuthenticationMixed();
authentication.LogonParametersType = typeof(AuthenticationStandardLogonParameters);
authentication.AddAuthenticationStandardProvider(typeof(PermissionPolicyUser));
authentication.AddIdentityAuthenticationProvider(typeof(PermissionPolicyUser));
SecurityStrategyComplex security = new SecurityStrategyComplex(typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), authentication);
return security;
});
#region Swagger
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "PAM_System.ODataWebService", Version = "v1" });
//Do you need to add accesstoken to URL when you need control the request in swagger?
//c.OperationFilter<AddAuthTokenHeaderParameter>();
});
// Customize the Swagger generator here
services.ConfigureSwaggerGen(options =>
{
// Use fully qualified schema object names to ensure uniqueness
options.CustomSchemaIds(configuration => configuration.FullName);
});
#endregion
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "PAM_System.ODataWebService v1"); });
}
else
{
app.UseHsts();
}
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseODataQueryRequest();
app.UseODataBatching();
app.UseRouting();
app.UseCors();
app.UseCookiePolicy();
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "PAM_System.ODataWebService v1");
c.RoutePrefix = "PAM_System.ODataWebService/swagger"; //set Root node access
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseDemoData(Configuration.GetConnectionString("XafApplication"));
}
}
Also I tried following code in my startup.cs, then I am able to see my Controller map into swagger but Action gets no response it’s just gets stuck there for long time
services.AddSwaggerGen(c =>
{
c.ResolveConflictingActions(apiDescriptions =>
{
var descriptions = apiDescriptions as ApiDescription[] ?? apiDescriptions.ToArray();
var first = descriptions.First(); // build relative to the 1st method
var parameters = descriptions.SelectMany(d => d.ParameterDescriptions).ToList();
first.ParameterDescriptions.Clear();
// add parameters and make them optional
foreach (var parameter in parameters)
if (first.ParameterDescriptions.All(x => x.Name != parameter.Name))
{
first.ParameterDescriptions.Add(new ApiParameterDescription
{
ModelMetadata = parameter.ModelMetadata,
Name = parameter.Name,
ParameterDescriptor = parameter.ParameterDescriptor,
Source = parameter.Source,
IsRequired = false,
DefaultValue = null
});
}
return first;
});
});