Prahlerfehler: Widersprüchliche Schema-IDs: Doppelte Schema-IDs für Typ A und B erkannt

76

Mit der Web-API und Swashbuckle zum Generieren von Swagger-Dokumentation habe ich zwei verschiedene Klassen mit demselben Namen in zwei verschiedenen Namespaces definiert. Wenn ich die Prahlerseite in meinem Browser öffne, heißt es

Widersprüchliche Schema-IDs: Doppelte Schema-IDs, die für die Typen A und B erkannt wurden. Eine mögliche Problemumgehung finden Sie in der Konfigurationseinstellung "UseFullTypeNameInSchemaIds"

vollständige Nachricht:

500: {"Message": "Ein Fehler ist aufgetreten.", "ExceptionMessage": "Konflikte mit Schema-IDs: Doppelte Schema-IDs für Typ A und B erkannt. Eine mögliche Problemumgehung finden Sie in der Konfigurationseinstellung" UseFullTypeNameInSchemaIds "," ExceptionType " ":" System.InvalidOperationException "," StackTrace ":" bei Swashbuckle.Swagger.SchemaRegistry.CreateRefSchema (Typ Typ) \ r \ n bei Swashbuckle.Swagger.SchemaRegistry.CreateInlineSchema (Typ Typ) \ r \ n bei Swashbuckle.S. SchemaRegistry.b__1f (JsonProperty prop) \ r \ n bei System.Linq.Enumerable.ToDictionary [TSource, TKey, TElement] (IEnumerable 1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 Vergleicher) \ r \ n bei Swashbuckle.Swagger.SchemaRegistry.CreateObjectSchema (JsonObjectContract jsonContract) \ r \ n bei Swashbuckle.Swagger.SchemaRegistry.CreateDefinitionSchema (Type type) \ r \ n bei Swashbuckle.Rw ) \ r \ n bei Swashbuckle.Swagger.SwaggerGenerator.CreateOperation (ApiDescription apiDesc, SchemaRegistry schemaRegistry) \ r \ n bei Swashbuckle.Swagger.SwaggerGenerator.CreatePathItem (IEnumerable 1 apiDescriptions, SchemaRegistry schemaRegistry)\r\n at Swashbuckle.Swagger.SwaggerGenerator.<>c__DisplayClass7.<GetSwagger>b__4(IGrouping2 group) \ r \ n bei System.Lumerq. TSource, TKey, TElement] (IEnumerable 1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 Vergleicher) \ r \ n bei Swashbuckle.Swagger.SwaggerGenerator.GetSwagger (String rootUrl, String apiVersion) \ r \ n bei Swashbuckle.Application.SwaggerDocsHandler.SendAsync (HttpRequestMessage request, CancellationToken n). Http.HttpMessageInvoker.SendAsync (HttpRequestMessage-Anforderung, CancellationToken CancellationToken) \ r \ n unter System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync (HttpRequestMessage-Anforderung, CancellationToken. HttpRequestMessage-Anforderung, CancellationToken CancellationToken) \ r \ n unter System.Web.Http.HttpServer.d__0.MoveNext () "} http: // localhost: 24215 / swagger / docs / v1

Ich möchte die Namen meiner Klassen nicht ändern. Wie kann ich es reparieren?

Mahdi Ataollahi
quelle

Antworten:

122

Jede Klasse im Swagger-JSON muss eine eindeutige Schema-ID haben.

Swashbuckler versucht, den Klassennamen nur als einfache Schema-ID zu verwenden. Wenn Sie jedoch zwei Klassen in unterschiedlichen Namespaces mit demselben Namen haben (wie Sie), funktioniert dies nicht.

Wie der Fehler andeutet, können Sie die Konfigurationseinstellung "UseFullTypeNameInSchemaIds *" für eine mögliche Problemumgehung verwenden (Update: in neueren Versionen nicht verfügbar).

In neueren Versionen können Sie das gleiche Verhalten über Optionen erreichen. CustomSchemaIds (x => x.FullName).

Hier ist ein Beispiel:

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

...

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

Weitere Informationen finden Sie unter http://wegotcode.com/microsoft/swagger-fix-for-dotnetcore/.

Ghebrehiywet
quelle
1
falls vorhanden ist hier von aspnetzero oder aspnetboilerplate oder abp community. Dieselbe Soulution gilt, fügen Sie einfach eine Option zu den Diensten hinzu. Fügen Sie SwaggerGen hinzu, wenn Sie Swagger aktivieren
Avi
1
Verursacht UseFullTypeNameInSchemaIds eine grundlegende Änderung für Clients, da der kurze Klassenname durch den langen Namespace.ClassName ersetzt wird?
Michael Freidgeim
53

Ich habe endlich einen Weg in Prahlerei-Konfigurationen gefunden. Gehen Sie zur App_Start\SwaggerConfig.csDatei und EnableSwaggerfügen Sie unter Lambda-Ausdruck diese Zeile hinzu:

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

Der vollständige Code lautet wie folgt:

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

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

        // other configs...
    })
    .EnableSwaggerUi(c =>
        // ....
    });
Mahdi Ataollahi
quelle
28

Ich verwende Asp.net Core 2.1. Dieser Fehler trat auf, als ich versuchte, die Swagger-Benutzeroberfläche anzuzeigen.

Ich habe das Problem folgendermaßen gelöst:

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

siehe Beispiel unten:

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);
        });
Hidan
quelle
14

Wenn Sie auskommentieren oder hinzufügen:

c.UseFullTypeNameInSchemaIds();

In diesem Abschnitt scheint es dasselbe zu tun.

Karl Merecido
quelle
1
In den letzten Versionen ist UseFullTypeNameInSchemaIds nicht verfügbar. Verwenden Sie c.CustomSchemaIds (x => x.FullName); stattdessen
Michael Freidgeim
4

Für Swashbuckle.AspNetCore 5.2.1 (unter .NET Core 3.1) scheinen der Swashbuckle-Konfigurations-API die in den älteren Lösungen beschriebenen Optionen zu fehlen. Stattdessen hat die folgende Änderung in der Startup.csfür mich funktioniert:

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

     // Tweak to the Schema generator
     c.SchemaGeneratorOptions = new SchemaGeneratorOptions {SchemaIdSelector = type => type.FullName};
  }
Carsten Führmann
quelle
3

Wenn Ihr Modell generische Typen enthält, sollten Sie Type.ToString()anstelle von verwenden Type.FullName, um die für den generischen Parametertyp generierten Assembly-Informationen zu entfernen und Ihre Schema-IDs konsistenter zu gestalten.

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

Beispiel zeigt den Unterschied auf 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
quelle
Wäre es ein großes Problem, wenn auf einem der Typen bereits ToString definiert wäre? Oder wenn ein Entwickler hereinkam und das später tat?
Chris