8

是否可以生成客户端代码,以便模型的类名具有完整的命名空间作为前缀?

那应该避免相同的类名冲突。

例子

com.foo.MyClass 

it.foo.MyClass

到目前为止,我得到的是MyClassMyClass2这并没有多大意义。

最好有,以防名称冲突,ComFooMyClass并且ItFooMyClass.

4

4 回答 4

5

我找到了使用自定义 SchemaNameGenerator 而不是自定义 TypeNameGenerator (我没有包信息)的解决方案。

internal class MySchemaNameGenerator : DefaultSchemaNameGenerator, ISchemaNameGenerator
{
    public override string Generate(Type type)
    {
        string retValue = base.Generate(type);
        // Quite ugly but do fix the concept
        if (retValue.Equals("BaseClass"))
        {
            retValue = type.FullName.Replace(".","_");
        }
        return retValue;
    }
}

始终通过设置进行设置:

 app.UseSwaggerUi(typeof(WebApiApplication).Assembly, new SwaggerUiSettings
                {
                    SchemaNameGenerator = new MySchemaNameGenerator(),
                    ...

这样我得到了更有意义的东西

"/api/test/models/base": {
      "get": {
        "tags": [
          "Test"
        ],
        "operationId": "Test_Get2",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "schema": {
              "$ref": "#/definitions/WebApi_Models_BaseClass"
            },
            "x-nullable": true
          }
        }
      }
    },
    "/api/test/models/extended": {
      "get": {
        "tags": [
          "Test"
        ],
        "operationId": "Test_Get3",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "schema": {
              "$ref": "#/definitions/ExtendedClass"
            },
            "x-nullable": true
          }
        }
      }
    },
    "/api/test/modelli/base": {
      "get": {
        "tags": [
          "Test"
        ],
        "operationId": "Test_Get4",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "schema": {
              "$ref": "#/definitions/WebApi_Modelli_BaseClass"
            },
            "x-nullable": true
          }
        }
      }
    },

即使多态性的鉴别器属性需要基本名称“BaseClass”。

于 2017-07-26T08:23:33.837 回答
5

让我更新 shadowsheep 对 NSwag 更新版本的回答:

services.AddSwaggerDocument(cfg => { cfg.SchemaNameGenerator = new CustomSchemaNameGenerator(); });

和:

internal class CustomSchemaNameGenerator : ISchemaNameGenerator
{
    public string Generate(Type type)
    {
        return type.FullName.Replace(".", "_");
    }
}
于 2019-12-07T11:15:09.430 回答
3

通过 C# 使用 NSwag 时,您可以提供自己的 TypeNameGenerator(通过设置对象)来自定义生成类名的方式。

于 2017-07-25T19:07:43.773 回答
0

生成完整的命名空间。您需要设置 API 以返回具有完整命名空间的 swagger

services.AddSwaggerGen(c =>
{
    ...  //any lines you aready have 
    c.CustomSchemaIds((type) => type.FullName); //show full namespace
}

您无法通过 NSwagStudio 生成客户端,您需要通过代码使用此解决方案https://stackoverflow.com/a/45311657/1818723

这是通过自己的代码生成客户端的现成代码

using NJsonSchema;
using NSwag;
using NSwag.CodeGeneration.CSharp;
using NSwag.CodeGeneration.OperationNameGenerators;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;

...

public async Task<string> GetClientCode(string swaggerUrl, CSharpClientGeneratorSettings settings)
{
    settings.OperationNameGenerator = new SingleClientFromOperationIdOperationNameGenerator();
    settings.CSharpGeneratorSettings.TypeNameGenerator = new MyTypeNameGenerator();
    var swagger = await GetAsync(swaggerUrl);
    var document = await OpenApiDocument.FromJsonAsync(swagger);
    var codeGen = new CSharpClientGenerator(document, settings);

    var code = codeGen.GenerateFile();
    return code;
}

public class MyTypeNameGenerator : ITypeNameGenerator
{
    public string Generate(JsonSchema schema, string typeNameHint, IEnumerable<string> reservedTypeNames)
    {
        if (typeNameHint == null && schema.IsEnumeration && schema.Title != null)
                return schema.Title; //for method argument when expected type is IEnumerable<Enum> (swagger definition must contain title - see last link) 

        return typeNameHint;   //this contains full namespace (assuming returned in swagger definition)
    }
}

private async Task<string> GetAsync(string uri)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

    using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
    using (Stream stream = response.GetResponseStream())
    using (StreamReader reader = new StreamReader(stream))
    {
        return await reader.ReadToEndAsync();
    }
}

这里关于枚举标题

https://github.com/RicoSuter/NSwag/issues/2103#issuecomment-853965927

于 2021-06-03T15:21:45.123 回答