108

Using Web API and using swashbuckle to generate swagger documentation, I defined two different classes with the same name in two different namespaces. when I open swagger page in my browser it says

Conflicting schemaIds: Duplicate schemaIds detected for types A and B. See the config setting - "UseFullTypeNameInSchemaIds" for a potential workaround

full message:

500 : {"Message":"An error has occurred.","ExceptionMessage":"Conflicting schemaIds: Duplicate schemaIds detected for types A and B. See the config setting - \"UseFullTypeNameInSchemaIds\" for a potential workaround","ExceptionType":"System.InvalidOperationException","StackTrace":" at Swashbuckle.Swagger.SchemaRegistry.CreateRefSchema(Type type)\r\n at Swashbuckle.Swagger.SchemaRegistry.CreateInlineSchema(Type type)\r\n at Swashbuckle.Swagger.SchemaRegistry.b__1f(JsonProperty prop)\r\n at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer)\r\n at Swashbuckle.Swagger.SchemaRegistry.CreateObjectSchema(JsonObjectContract jsonContract)\r\n at Swashbuckle.Swagger.SchemaRegistry.CreateDefinitionSchema(Type type)\r\n at Swashbuckle.Swagger.SchemaRegistry.GetOrRegister(Type type)\r\n at Swashbuckle.Swagger.SwaggerGenerator.CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaRegistry)\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()"} http://localhost:24215/swagger/docs/v1

I don't want to change my classes' names. How can I fix it?

Jim G.
  • 15,141
  • 22
  • 103
  • 166
Mahdi Ataollahi
  • 4,544
  • 4
  • 30
  • 38

7 Answers7

166

Every class in the swagger JSON must have a unique schemaId.

Swashbuckler tries to just use the class name as a simple schemaId, however if you have two classes in different namespaces with the same name (as you do) this will not work.

As the error suggests, you can use the config setting "UseFullTypeNameInSchemaIds*" for a potential workaround (Update: not available in recent versions)

In newer versions you can achieve the same behavior via options.CustomSchemaIds(x => x.FullName).

Here is an example:

   services.ConfigureSwaggerGen(options =>
   {
       //your custom configuration goes here

...

  // UseFullTypeNameInSchemaIds replacement for .NET Core
       options.CustomSchemaIds(x => x.FullName);
   });

for more information http://wegotcode.com/microsoft/swagger-fix-for-dotnetcore/

Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170
Ghebrehiywet
  • 884
  • 3
  • 12
  • 20
  • 1
    if in case any is here from aspnetzero or aspnetboilerplate or abp community. Same soulution applies just add option to services.AddSwaggerGen when you enable swagger – Avi Oct 24 '18 at 13:55
  • 2
    Will UseFullTypeNameInSchemaIds cause breaking change for clients as short ClassName will be replaced with long Namespace.ClassName? – Michael Freidgeim May 13 '19 at 13:16
  • That seems to break the xml comments and nothing is displayed as schema. Is there any workaround? – diegosasw Sep 01 '22 at 14:23
  • I stil get an error because I use class in a class, so the output contains '+' My solution: CustomSchemaIds(x => x.FullName?.Replace('+', '-'); – Ariën Feb 23 '23 at 18:28
68

I finally found a way in swagger configs. Go to App_Start\SwaggerConfig.cs file and under EnableSwagger lambda expression add this line:

c.SchemaId(x => x.FullName);

Full code is like this:

GlobalConfiguration.Configuration 
    .EnableSwagger(c =>
    {
        // your configs...

        c.SchemaId(x => x.FullName);

        // other configs...
    })
    .EnableSwaggerUi(c =>
        // ....
    });
Mahdi Ataollahi
  • 4,544
  • 4
  • 30
  • 38
  • I have provided my Swagger.json file to my clients. If I change accordingly to the above, will this change break the current consumers of my API? – Kevy Granero Jun 25 '21 at 09:21
  • This is the correct answer when using asp.net framework. You can find the relevant documentation [here](https://github.com/domaindrivendev/Swashbuckle.WebApi/tree/5489aca0d2dd7946f5569341f621f581720d4634#usefulltypenamesinschemaids). – somethingRandom Nov 29 '22 at 12:55
34

I am using Asp.net Core 2.1. This error resulted when I tried to show Swagger UI.

I solved the problem this way:

In Starup.cs, in ConfigureServices() add c.CustomSchemaIds(i => i.FullName);

see example below:

services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info
            {
                Title = "ASP.NET Core 2.1+ ConsumerApp API",
                Version = "v1"
            });
            // Set the comments path for the Swagger JSON and UI.
            var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
            c.IncludeXmlComments(xmlPath);
            c.CustomSchemaIds(i => i.FullName);
        });
Nick
  • 3,454
  • 6
  • 33
  • 56
Hidan
  • 391
  • 4
  • 4
16

If you comment out or add:

c.UseFullTypeNameInSchemaIds();

In that section, it seems to do same thing.

Paul T.
  • 4,703
  • 11
  • 25
  • 29
Karl Merecido
  • 344
  • 3
  • 7
13

For Swashbuckle.AspNetCore 5.2.1 (on .NET Core 3.1), the Swashbuckle configuration API seems to lack the options described in the older solutions. Instead, the following change in the Startup.cs worked for me:

  services.AddSwaggerGen(c =>
  {
     // Existing configuration

     // Tweak to the Schema generator
     c.SchemaGeneratorOptions = new SchemaGeneratorOptions {SchemaIdSelector = type => type.FullName};
  }
Carsten Führmann
  • 3,119
  • 4
  • 26
  • 24
6

If your model contains generic types, consider using Type.ToString() instead of Type.FullName to get rid of assembly information generated for generic parameter type and make your schema ids more consistent.

services.AddSwaggerGen(options =>
{
    options.CustomSchemaIds(type => type.ToString());
});

Example showing the difference on List<string>:

Console.WriteLine(typeof(List<string>).FullName);
Console.WriteLine(typeof(List<string>).ToString());

// Output:
//    System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
//    System.Collections.Generic.List`1[System.String]
mguoth
  • 61
  • 1
  • 2
  • Would there be a big problem if one of the types already has ToString defined on it? Or if a developer came in and did that later? – Christopher Apr 23 '20 at 16:01
  • 1
    @Chris You generally override `ToString` in the class, but you can't (easily) override `Type.ToString`. So, no, not a problem. – wensveen May 06 '21 at 11:38
-1

In my case, I had 2 of the same classes in my 2 microservice projects (A, and B).

When I opened the dependencies folder in project(A), I found that I added the other project(B) as a reference to this project by mistake.

After removing the dependency between my two projects the conflict was solved.