在具有相同名称的不同名称空间中招摇不同的类不起作用

Posted

技术标签:

【中文标题】在具有相同名称的不同名称空间中招摇不同的类不起作用【英文标题】:Swagger different classes in different namespaces with same name don't work 【发布时间】:2019-10-21 20:14:26 【问题描述】:

我有(超过)两个 Api POST 端点。每个都需要一个json作为参数。但是当我在两个端点参数类中使用相同的类名 Payload 时,Swagger 不起作用。当我改变其中之一时,例如从 PayloadPayload1 比它有效。 当然,我在包装类中设置了正确的名称空间,以便它找到 Payload。但我希望每次都使用相同的名称“Payload”。 如何使用相同的类名Payload 我可以在这两种情况下保留 json 名称“Payload”,并为属性设置不同的名称(“Payload1”、“Payload2”)。有用。但是也可以有相同的属性名称。,

端点 A

[HttpPost()]

公共异步任务 PostPerson([FromBody]JsonWrapperA jsonWrapperA)

namespace myProject.A

    public class JsonWrapperA
    
        [JsonProperty("name", Required = Required.AllowNull)]
        public string Name  get; set; 

        [JsonProperty("payload", Required = Required.AllowNull)]
        public Payload Payload  get; set; 
    

    public class Payload
    
        [JsonProperty("value", Required = Required.AllowNull)]
        public double Value  get; set; 
    

端点 B

[HttpPost()]

公共异步任务 PostCompagn([FromBody]JsonWrapperB jsonWrapperB)

namespace myProject.B

    public class JsonWrapperB
    
        [JsonProperty("compagny", Required = Required.AllowNull)]
        public string Compagny  get; set; 

        [JsonProperty("payload", Required = Required.AllowNull)]
        public Payload Payload  get; set; 
    

    public class Payload
    
        [JsonProperty("age", Required = Required.AllowNull)]
        public double Age get; set; 
    

【问题讨论】:

这能回答你的问题吗? swagger error: Conflicting schemaIds: Duplicate schemaIds detected for types A and B 【参考方案1】:

默认情况下,swagger 将尝试为作为 API 端点的返回类型或参数类型的对象构建其架构 ID,并将在文档的“模型”部分显示这些对象。它将根据对象的类名构建这些模式 ID。

当您尝试将两个或多个类命名相同时,即使它们位于不同的命名空间中,您也会收到 schemaIds 冲突错误:

InvalidOperationException:冲突的 schemaIds:为类型 NamespaceOne.MyClass 和 NamespaceTwo.MyClass 检测到相同的 schemaIds。请参阅配置设置 - “CustomSchemaIds”了解解决方法

这意味着需要配置 Swagger 以更改其生成其 SchemaId 的方式。您可以简单地告诉 swagger 使用对象完全限定名称,该名称将在 schemaIds 中包含命名空间。您可以在ConfigureServices 方法中的Startup.cs 文件中执行此操作,如下所示:

//add using statement for Swagger in Startup.cs
using Swashbuckle.AspNetCore.Swagger;

...

public void ConfigureServices(IServiceCollection services)

    services.AddSwaggerGen(config =>
    
        //some swagger configuration code.

        //use fully qualified object names
        config.CustomSchemaIds(x => x.FullName);
    

【讨论】:

我们如何在 spring boot java 中做同样的事情? @SouravMukherjee 我对 Spring Boot 框架不太熟悉,但我相信原理是一样的。您将必须了解如何挂钩 Spring 的启动事件,然后弄清楚如何配置您正在使用的 Swagger 版本。这个问题特定于名为 Swashbuckle 的 ASP.NET swagger 包装器,因此它与 Spring 可用的不同。这是一个swagger wrapper for Spring called SpringFox,可能会有所帮助。我建议为 java Spring Boot 打开一个特定的招摇问题。【参考方案2】:

使用 Swashbuckle.AspNetCore 版本 5.5.1 我遇到了同样的问题,所以我使用 JustSomeDude 答案解决了这个问题,但之后所有实体都以全名显示,所以我需要一种只显示名称的方法。这就是我所做的:

    options.CustomSchemaIds(x => x.FullName); // Enables to support different classes with the same name using the full name with namespace
    options.SchemaFilter<NamespaceSchemaFilter>(); // Makes the namespaces hidden for the schemas

使用这个过滤器类:

     public class NamespaceSchemaFilter : ISchemaFilter

    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    
        if (schema is null)
        
            throw new System.ArgumentNullException(nameof(schema));
        

        if (context is null)
        
            throw new ArgumentNullException(nameof(context));
        

        schema.Title = context.Type.Name; // To replace the full name with namespace with the class name only
    

【讨论】:

以上是关于在具有相同名称的不同名称空间中招摇不同的类不起作用的主要内容,如果未能解决你的问题,请参考以下文章

C#将类导入另一个类不起作用

C++ 多个具有相同名称的类

如果它们位于不同的文件夹中,是不是可以有两个具有相同名称的类?

为在不同名称空间中具有相同名称的两个服务设置两个入口

Rails 和 RSpec:在不同的命名空间(模块)中测试具有相同名称的控制器

Laravel中的路由问题,带有多个控制器和具有相同名称的不同路由[关闭]