简体   繁体   中英

How to have different names for my API DTO's (based on the generator) with Nswag?

I have a .NET 5.0 ASP.NET Core project and I am using Nswag to generate an API client. Let's say I have the following API model:

public class GetFooListResponseModel
{
    public string Bar { get; set; }
}

What I would like is 2 things. Let's start with the basic one.

  • How do I make the generated API Client's model name a different one than the one in my project? For example, I want the generated typescript model to be called Foo instead of GetFooListResponseModel .
  • Could I make them have different names based on the client it is generating? For example, for my C# Client I am completely fine with the existing model name, but the typescript one needs to be changed. If this is not possible it's no big deal, but it would be nice.

Thank you very much!

You can use SchemaNameGenerator to customise the model name. You can refer shadowsheep's answer. To generate completely new Model name you can use CustomeAttribute with SchemaNameGenerator.

public class ClientModelAttribute : Attribute
{
    public string Name { get; set; }
    public ClientModelAttribute(string name)
    {
        Name = name;
    }
}

  internal class CustomSchemaNameGenerator : ISchemaNameGenerator
{
    public string Generate(Type type)
    {
        var attrs = type.GetCustomAttributes(typeof(ClientModelAttribute),true);

        foreach (var attr in attrs)
        {
            if(attr is ClientModelAttribute)
            {
                ClientModelAttribute clientModel = attr as ClientModelAttribute;
                return clientModel.Name;
            }
        }

        return type.FullName;
    }
}

Model Class with CustomAttribute

[ClientModel("Foo")]
public class WeatherForecast
{
    public DateTime Date { get; set; }

    public int TemperatureC { get; set; }

    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

    public string Summary { get; set; }
}

update ConfigureServices

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

swagger.json

 "paths": {
"/WeatherForecast": {
  "get": {
    "tags": [
      "WeatherForecast"
    ],
    "operationId": "WeatherForecast_Get",
    "responses": {
      "200": {
        "x-nullable": false,
        "description": "",
        "schema": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Foo"
          }
        }
      }
    }
  }
}

You can simply create a injectable service called 'FooService' for communicating with backend services using HTTP Request. Specify the model/class (you can create any name you want) being returned from your API in getFooListResponse() . The naming not necessary must be the same with GetFooListResponseModel , as long the attributes and its data type of the model/class are same.

foo.service.ts

@Injectable()
export class FooService 
{
  constructor(
  protected http: HttpClient
  ) {}

  getFooListResponse() {
    const endpointUrl = "myEndpointUrl";
    return this.http.get<Foo>(endpointUrl);
  }
}

foo.model.ts

export class Foo {
    public Bar: string;
}

Sometimes, the best solution is the simplest. Try creating a windows/message asking the user what they would like their module name to be that would trigger once the program starts?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM