招摇错误:冲突的schemaIds:为类型A和B检测到重复的schemaIds
Posted
技术标签:
【中文标题】招摇错误:冲突的schemaIds:为类型A和B检测到重复的schemaIds【英文标题】:swagger error: Conflicting schemaIds: Duplicate schemaIds detected for types A and B 【发布时间】:2018-02-14 17:25:24 【问题描述】:使用 Web API 并使用 swashbuckle 生成 swagger 文档, 我在两个不同的命名空间中定义了两个具有相同名称的不同类。当我在浏览器中打开招摇页面时,它说
冲突的 schemaIds:针对类型 A 和 B 检测到重复的 schemaIds。请参阅配置设置 - “UseFullTypeNameInSchemaIds”了解潜在的解决方法
完整消息:
500 : "Message":"An error has occurred.","ExceptionMessage":"Conflicting schemaIds:为类型 A 和 B 检测到重复的 schemaIds。请参阅配置设置 - \"UseFullTypeNameInSchemaIds\" 以了解潜在的解决方法" "ExceptionType":"System.InvalidOperationException","StackTrace":" 在 Swashbuckle.Swagger.SchemaRegistry.CreateRefSchema(Type type)\r\n 在 Swashbuckle.Swagger.SchemaRegistry.CreateInlineSchema(Type type)\r\n 在 Swashbuckle .Swagger.SchemaRegistry.b__1f(JsonProperty prop)\r\n 在 System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable
1 source, Func
2 keySelector, Func2 elementSelector, IEqualityComparer
1 比较器)\r\n 在 Swashbuckle .Swagger.SchemaRegistry.CreateObjectSchema(JsonObjectContract jsonContract)\r\n 在 Swashbuckle.Swagger.SchemaRegistry.CreateDefinitionSchema(类型类型)\r\n 在 Swashbuckle.Swagger.SchemaRegistry.GetOrRegister(类型类型)\r\n 在 Swashbuckle.Swagger .SwaggerGenerator.CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaRegistry)\r\n 在 Swashbuckle.Swagger.S waggerGenerator.CreatePathItem(IEnumerable1 apiDescriptions, SchemaRegistry schemaRegistry)\r\n at Swashbuckle.Swagger.SwaggerGenerator.<>c__DisplayClass7.<GetSwagger>b__4(IGrouping
2 group)\r\n at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func
2 keySelector, Func2 elementSelector, IEqualityComparer
1 comparer)\r\n at Swashbuckle.Swagger.SwaggerGenerator.GetSwagger(字符串 rootUrl,字符串 apiVersion)\r\n 在 Swashbuckle.Application.SwaggerDocsHandler.SendAsync(HttpRequestMessage 请求,CancellationToken cancelToken)\r\n 在 System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage 请求, CancellationToken cancelToken)\r\n 在 System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancelToken)\r\n 在 System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancelToken)\r \n 在 System.Web.Http.HttpServer.d__0.MoveNext()" http://localhost:24215/swagger/docs/v1
我不想更改我的班级名称。我该如何解决?
【问题讨论】:
【参考方案1】: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/
【讨论】:
如果有任何来自 aspnetzero 或 aspnetboilerplate 或 abp 社区的信息。相同的解决方案仅适用于启用 swagger 时向 services.AddSwaggerGen 添加选项 UseFullTypeNameInSchemaIds 是否会导致客户端发生重大更改,因为短 ClassName 将被长 Namespace.ClassName 替换?【参考方案2】:我终于在 swagger configs 中找到了一种方法。转到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 的当前使用者?【参考方案3】:我使用的是 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);
);
【讨论】:
【参考方案4】:如果你注释掉或添加:
c.UseFullTypeNameInSchemaIds();
在那个部分,它似乎做同样的事情。
【讨论】:
在最近的版本中 UseFullTypeNameInSchemaIds 不可用。使用 c.CustomSchemaIds(x => x.FullName);而是【参考方案5】:对于 Swashbuckle.AspNetCore 5.2.1(在 .NET Core 3.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 您通常会在课堂上覆盖ToString
,但不能(轻松)覆盖Type.ToString
。所以,不,不是问题。以上是关于招摇错误:冲突的schemaIds:为类型A和B检测到重复的schemaIds的主要内容,如果未能解决你的问题,请参考以下文章