InvalidOperationException: Can't use schemaId .. 相同的 schemaId 已用于类型

Joh*_*yer 11 c# odata swagger asp.net-core-3.1

我收到以下错误。

InvalidOperationException: Can't use schemaId "$Registration" for type "$PortalService.Models.Registration". The same schemaId is already used for type "$PortalService.Models.Registration"
Run Code Online (Sandbox Code Playgroud)

我已经尝试了以下链接中的建议,但没有成功。

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

我在模型中只有一个注册类。我曾尝试重命名课程但没有成功。

我正在使用 OData .Net Core 3.1 项目。

配置 Swagger 如下

 services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
            services.AddSwaggerGen(c =>
            {
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = @"JWT Authorization header using the Bearer scheme. \r\n\r\n 
                      Enter 'Bearer' [space] and then your token in the text input below.
                      \r\n\r\nExample: 'Bearer 12345abcdef'",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    Scheme = "Bearer"
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement()
                  {
                    {
                      new OpenApiSecurityScheme
                      {
                        Reference = new OpenApiReference
                          {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                          },
                          Scheme = "oauth2",
                          Name = "Bearer",
                          In = ParameterLocation.Header,

                        },
                        new List<string>()
                      }
                    });
            });
Run Code Online (Sandbox Code Playgroud)

使用 Swagger 如下

  app.UseSwagger(c =>
            {
                //c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.BasePath = basepath);

                 
                c.PreSerializeFilters.Add((swaggerDoc, httpReq) => {
                    Microsoft.OpenApi.Models.OpenApiPaths paths = new Microsoft.OpenApi.Models.OpenApiPaths();
                    foreach (var path in swaggerDoc.Paths)
                    {
                        paths.Add(path.Key.Replace(path.Key, basepath + path.Key), path.Value);
                    }
                    swaggerDoc.Paths = paths;
                });
            });
            app.UseSwaggerUI(
                options =>
                {
                    options.RoutePrefix = string.Empty;

                    // build a swagger endpoint for each discovered API version

                    foreach (var description in provider.ApiVersionDescriptions)
                    {
                        options.SwaggerEndpoint($"{basepath}/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                    }

                });
Run Code Online (Sandbox Code Playgroud)

这似乎与

Swagger 因循环模型引用而崩溃

我发现如果我从注册中注释掉合作伙伴的反向引用,错误就会消失,但我需要这个引用。我不清楚如何解决这种情况。

[ForeignKey("Partner")]
[DataMember(Name = "PartnerOID")]
[Column(TypeName = "VARCHAR(100)")]
public string PartnerOID { get; set; }
//public virtual Partner Partner { get; set; }
Run Code Online (Sandbox Code Playgroud)

Eri*_*rik 34

试试这个约翰:https : //github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1607#issuecomment-607170559 帮助了我。

我能理解正在发生的事情;我有几个带有“状态”或“类型”的枚举。使用 options.CustomSchemaIds( type => type.ToString() ); 解决了这个问题。

  • 使用 `type.FullName` 也是一个好方法...... (20认同)
  • https://github.com/swagger-api/swagger-ui/issues/7911 + 号仍然存在问题。`c.CustomSchemaIds(s =&gt; s.FullName.Replace("+", "."));` 避免了这个问题 (3认同)

Mau*_*tti 7

根据 Erik 的回复和提供的链接,唯一需要的更改是在您的Startup.cs内部方法中ConfigureServices

您应该添加以下内容:

services.AddSwaggerGen(options =>
{
    options.CustomSchemaIds(type => type.ToString());
});
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢,“AddSwaggerGen”的提及很有帮助。我的问题解决了。 (5认同)

小智 7

我一直在使用options.CustomSchemaIds(type => type.ToString());options.CustomSchemaIds(type => $"{type.Name}_{System.Guid.NewGuid().ToString().Replace("-", "")}")来创建模式名称的唯一性。两者都会导致我讨厌的更长的模式名称。

这是一种跟踪名称重复的不同方法,我更喜欢这种方法。

辅助类:

internal static class SwashbuckleSchemaHelper
{
   private static readonly Dictionary<string, int> _schemaNameRepetition = new Dictionary<string, int>();

   public static string GetSchemaId(Type type)
   {
      string id = type.Name;

      if (!_schemaNameRepetition.ContainsKey(id))
          _schemaNameRepetition.Add(id, 0);

      int count = (_schemaNameRepetition[id] + 1);
      _schemaNameRepetition[id] = count;

      return type.Name + (count > 1 ? count.ToString() : "");
   }
}
Run Code Online (Sandbox Code Playgroud)

用法:

options.CustomSchemaIds(type => SwashbuckleSchemaHelper.GetSchemaId(type));
Run Code Online (Sandbox Code Playgroud)

如果类名重复,结果如下。

  • 发票
  • 行项目
  • 地位
  • 状态2