Swagger错误:schemaIds冲突:检测到类型A和B的重复schemaIds。

112
使用Web API并使用Swashbuckle生成Swagger文档时,我在两个不同的命名空间中定义了两个具有相同名称的不同类。当我在浏览器中打开Swagger页面时,它会显示以下信息:
“冲突的schemaIds:检测到类型A和B的重复schemaIds。请参见配置设置 - “UseFullTypeNameInSchemaIds”以获取潜在解决方法。”
完整消息:
500 : {"Message":"发生错误。","ExceptionMessage":"存在冲突的schemaIds:检测到类型A和B的重复schemaIds。请参见配置设置 -“UseFullTypeNameInSchemaIds”以获取潜在解决方法","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

我不想改变我的类名,该怎么办?

9个回答

169

Swagger JSON中的每个类必须具有唯一的schemaId。

Swashbuckler尝试仅使用类名作为简单的schemaId,但是如果您在不同命名空间中有两个名称相同的类(就像您所拥有的那样),则这种方法将无法正常工作。

如错误提示所示,你可以使用配置设置“UseFullTypeNameInSchemaIds*”来尝试解决问题(更新:最近的版本中不再支持该设置)

在较新的版本中,你可以通过选项CustomSchemaIds(x => x.FullName)来实现相同的行为。

这是一个例子:

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

...

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

了解更多信息,请访问http://wegotcode.com/microsoft/swagger-fix-for-dotnetcore/


1
如果您是来自 aspnetzero、aspnetboilerplate 或 abp 社区的开发者,请注意:在启用 Swagger 时,可以通过向 services.AddSwaggerGen 添加选项来实现相同的解决方案。 - Avi
2
使用FullTypeNameInSchemaIds会对客户端造成破坏性变更吗?因为短的ClassName将被替换为长的Namespace.ClassName。 - Michael Freidgeim
似乎这会破坏XML注释,导致模式未显示。有什么解决方法吗? - diegosasw
我仍然会因为在类中使用类而出现错误,所以输出包含“+”。我的解决方案:CustomSchemaIds(x => x.FullName?.Replace('+', '-')); - Ariën

68

我终于在Swagger配置中找到了一种方法。转到App_Start\SwaggerConfig.cs文件,在EnableSwagger lambda表达式下添加此行:

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

完整的代码如下:

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

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

        // other configs...
    })
    .EnableSwaggerUi(c =>
        // ....
    });

我已经向我的客户提供了Swagger.json文件。如果我按照上述更改,这个更改会破坏当前使用我的API的消费者吗? - Kevy Granero
这是在使用asp.net框架时的正确答案。您可以在此处找到相关文档。 - somethingRandom

34

我正在使用Asp.net Core 2.1。当我尝试显示Swagger UI时出现了此错误。

我是这样解决问题的:

Starup.cs文件中,在ConfigureServices()方法中添加c.CustomSchemaIds(i => i.FullName);

请参考以下示例:

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);
        });

16
如果您注释或添加了以下内容:
c.UseFullTypeNameInSchemaIds();

在那个部分,它似乎做同样的事情。


4
在最新版本中,UseFullTypeNameInSchemaIds不再可用。 请改用c.CustomSchemaIds(x=>x.FullName)代替。 - Michael Freidgeim
不再兼容 - Urasquirrel

14
对于.NET Core 3.1 上的 Swashbuckle.AspNetCore 5.2.1,Swashbuckle 配置 API 似乎缺乏旧版解决方案中描述的选项。相反,在 Startup.cs 中进行以下更改对我有效:

对于.NET Core 3.1上的Swashbuckle.AspNetCore 5.2.1,Swashbuckle配置API似乎缺乏旧版本解决方案中所述的选项。相反,在Startup.cs中进行以下更改对我有效:

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

     // Tweak to the Schema generator
     c.SchemaGeneratorOptions = new SchemaGeneratorOptions {SchemaIdSelector = type => type.FullName};
  }

6
如果你的模型包含泛型类型,请考虑使用 Type.ToString() 而不是 Type.FullName,这样可以去掉为泛型参数类型生成的程序集信息,并使你的模式 ID 更加一致。
services.AddSwaggerGen(options =>
{
    options.CustomSchemaIds(type => type.ToString());
});

示例展示了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]

如果其中一个类型已经定义了ToString,会有大问题吗?或者如果开发人员后来这样做了呢? - Chris
1
@Chris 通常你会在类中重写 ToString 方法,但是你不能(轻易地)重写 Type.ToString。所以,不,这不是一个问题。 - wensveen

0
我的问题只是与嵌套类有关,我不想显示我的类的完整命名空间,所以我只是从完整名称的开头删除了命名空间,这样仍然可以修复嵌套类,因为它们的输出形式为Order_OrderItem
options.CustomSchemaIds(type => type.FullName.TrimStart(type.Namespace + "."));

0
如果您在负载中使用通用类型,并且正在使用Nswag代理客户端,那么您应该考虑这样做。
services.AddSwaggerGen(options =>
{
    options.CustomSchemaIds(type => type.ToString().Replace("`1", ""));
});

避免使用Nswag时出现这种类型的输出是为了一个原因。

enter image description here

Replace("`1", "") 将格式化泛型类型,并使客户端更清晰:

enter image description here


-1
在我的情况下,我在我的两个微服务项目(A和B)中有两个相同的类。
当我打开项目(A)中的依赖项文件夹时,我发现我错误地将另一个项目(B)添加为该项目的引用。
在删除我两个项目之间的依赖关系后,冲突问题得到解决。

你遇到了同样的错误吗?我觉得这个答案很难与问题相关联。 - Dennis Dyallo
你有同样的错误吗?我觉得这个答案很难与问题相关联。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接