3

In my web api, I have 2 Get Methods, One to get all clients and one to get client by ID

  [HttpGet]
    public async Task<IHttpActionResult> GetClients()
    {
        var telemetry = new TelemetryClient();
        try
        {
            var roles = await CosmosStoreHolder.Instance.CosmosStoreClient.Query().ToListAsync();
            return Ok(roles);
        }
        catch (System.Exception ex)
        {
            string guid = Guid.NewGuid().ToString();
            var dt = new Dictionary<string, string>
            {
                { "Error Lulo: ", guid }
            };

            telemetry.TrackException(ex, dt);
            return BadRequest("Error Lulo: " + guid);
        }
    }

    [HttpGet]
    public async Task<IHttpActionResult> GetClient(string clientId)
    {     
        var telemetry = new TelemetryClient();
        try
        {
            var clientStore = CosmosStoreHolder.Instance.CosmosStoreClient;
            var client = await clientStore.Query().FirstOrDefaultAsync(x => x.Id == clientId);
            if (client == null)
            {
                return NotFound();
            }
            return Ok(client);
        }
        catch (System.Exception ex)
        {
            telemetry.TrackException(ex);
            return BadRequest("Unknown error");
        }
    }

I just installed swashbucckle and configured according to this:

https://www.c-sharpcorner.com/article/implementing-swagger-in-web-api/

However I get the error below

500 : {"Message":"An error has occurred.","ExceptionMessage":"Not supported by Swagger 2.0: Multiple operations with path 'api/Client' and method 'GET'. See the config setting - \"ResolveConflictingActions\" for a potential workaround","ExceptionType":"System.NotSupportedException","StackTrace":" at Swashbuckle.Swagger.SwaggerGeneratorOptions.DefaultConflictingActionsResolver(IEnumerable1 apiDescriptions)\r\n at Swashbuckle.Swagger.SwaggerGenerator.CreatePathItem(IEnumerable1 apiDescriptions, SchemaRegistry schemaRegistry)\r\n at Swashbuckle.Swagger.SwaggerGenerator.<>c__DisplayClass7.<GetSwagger>b__4(IGrouping2 group)\r\n at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer)\r\n at Swashbuckle.Swagger.SwaggerGenerator.GetSwagger(String rootUrl, String apiVersion)\r\n at Swashbuckle.Application.SwaggerDocsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.HttpServer.d__0.MoveNext()"} https://webapi-app.azurewebsites.net/swagger/do`cs/v1

Luis Valencia
  • 32,619
  • 93
  • 286
  • 506
  • 1
    I don't think you have identified the correct problem. You have 2 different functions with /similar/ names (GetClients vs GetClient). Swagger should have no problems with this. – Neil Oct 09 '19 at 12:03
  • 1
    Do you have a second function called `GetClient` that has a different set of parameters? – Neil Oct 09 '19 at 12:03
  • See if this helps: [Not supported by Swagger 2.0: Multiple operations with path](https://stackoverflow.com/q/39601890/113116), [Web API: Same Method with different HTTP Verbs](https://stackoverflow.com/q/35000024/113116), [API Routes: Multiple operations with path](https://stackoverflow.com/q/49056556/113116) – Helen Oct 09 '19 at 12:16
  • Thanks @Neil I checked and I dont have duplicated endpoints, this is indeed rare – Luis Valencia Oct 09 '19 at 12:28
  • Test changing `clientId` to int `GetClient(int clientId)` just a test see if the path is different... – Helder Sepulveda Oct 09 '19 at 12:56
  • set the attribute on top of both methods [Route(api/GetClients] and [Route(api/GetClient)] – JohnChris Oct 09 '19 at 13:31
  • check this, is the same problem https://stackoverflow.com/questions/39412998/swashbuckle-set-manualy-operationid the fix was to specify manual one by one the name for swagger – SilentTremor Oct 09 '19 at 13:33

1 Answers1

5

Your problem is caused by the string parameter, strings are nullable by default.
The routes of your actions:

  • GetClients()
  • GetClient(string clientId)

will be the same.

If it was an integer the route will look like:
/api/Controller/{clientId}
and will not conflict with the GetClients.

Changing data type might not be an option, you might be forced into using routes:


Looking at some of my examples I found this controller using routes and multiple Gets:

http://swagger-net-test.azurewebsites.net/swagger/ui/index?filter=Location#/

You can see I have multiple gets under the same controller, but they do have slightly different actions:

[RoutePrefix("Location")]
public class LocationController : ApiController
{
    [Route("Get1")]
    public GeolocateResponse Get1([FromUri] GeolocateResponse x)
    {
        return x;
    }

    [Route("Get2")]
    public Location Get2([FromUri] Location x)
    {
        return x;
    }
Helder Sepulveda
  • 15,500
  • 4
  • 29
  • 56