---
# System prepended metadata

title: Generate TypeScript Client  from dotnet API

---

# Generate TypeScript Client  from dotnet API  
https://blog.logrocket.com/generate-typescript-csharp-clients-nswag-api/

## Introdution
To generate a TypeScript client or a C# client from a dotnet API using NSwag, we will build five projects to demo. 
1. The `api` project will implement an endpoint that provides a `User.get()` restful API and a `swagger` HTML page. 
2. The `api_generator` project will generate the TypeScript/C# client code.  
3. The `client` project will create a `Vite-React` client project which will demo `multiple fetching function`. 
4. The `client-console` project will create a dotnet console app which using `C# client code` generated by `api-generator` to fetch endpoint.


the final folder structure will be like :
```
.
├── README.md
├── api
│   ├── Controllers
│   ├── Models
│   ├── Program.cs
│   ├── Properties
│   ├── WeatherForecast.cs
│   ├── api.csproj
│   ├── appsettings.Development.json
│   ├── appsettings.json
│   ├── bin
│   └── obj
├── api_generator
│   ├── Program.cs
│   ├── api_generator.csproj
│   ├── api_generator.sln
│   ├── bin
│   └── obj
├── client
│   ├── dist
│   ├── index.html
│   ├── node_modules
│   ├── package.json
│   ├── public
│   ├── src
│   ├── tsconfig.json
│   ├── tsconfig.node.json
│   ├── vite.config.ts
│   └── yarn.lock
├── client-console
│   ├── Program.cs
│   ├── bin
│   ├── client-console.csproj
│   ├── clients.cs
│   └── obj
├── node-ts
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── src
│   ├── tsconfig.json
│   └── yarn.lock
├── package.json
└── yarn.lock
```


## Step 1 : Setup folder structure
```bash
mkdir api
mkdir api_generator
mkdir client
mkdir client-console
mkdir node-ts
```
## Step 2 : Create API end point project
```bash
cd api
dotnet new webapi -o .
dotnet remove package Swashbuckle.AspNetCore
dotnet add package NSwag.AspNetCore
dotnet add package Microsoft.AspNetCore.Cors
dotnet new gitignore
```
Then create a folder witch named `Models` and create `UserModle.cs` in this folder
```C#
namespace api.Models;

public class UserModel
{
    public string Name { get; set; }
    public string? Email { get; set; }
}
```
Let create `UserController` in Controllers folder
you can see the source code that has a `[HttpGet(Name = "GetUser")]` function which providing a api to get the UserModels.
```C#
using System.Net.NetworkInformation;
using System.Runtime.InteropServices.ComTypes;
using System.IO;
using api.Models;
using Microsoft.AspNetCore.Mvc;

namespace api.Controllers;

[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
    private List<UserModel> userList = new List<UserModel>(){
        new UserModel(){

            Name = "Adem",
            Email= "adem@pic.net"
        },
        new UserModel(){
            Name="Ted",
            Email = "ted@pic.net"
        }
    }

    ;

    private readonly ILogger<UserController> _logger;

    public UserController(ILogger<UserController> logger)
    {
        _logger = logger;
    }

    [HttpGet(Name = "GetUser")]
    public IEnumerable<UserModel> Get()
    {
        return userList;
        // yield return new UserModel() { Name = "Adem" };
    }
}


```
and the most important things is  changing some code  in `Program.cs`

1. change `builder.Services.AddSwaggerGen();` to `builder.Services.AddSwaggerDocument();`
2. change ` app.UseSwagger();` and `app.UseSwaggerUi();` to `app.UseOpenApi();`,`app.UseSwaggerUi3();`
```C#
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    // app.UseSwagger();
    // app.UseSwaggerUi();
    app.UseDeveloperExceptionPage();
    // Register the Swagger generator and the Swagger UI middlewares
    app.UseOpenApi();
    app.UseSwaggerUi3();
}
```
3. Add Cors
```C#
const string ALLOW_DEVELOPMENT_CORS_ORIGINS_POLICY = "AllowDevelopmentSpecificOrigins";
const string LOCAL_DEVELOPMENT_URL = "http://127.0.0.1:5173"; //your client url

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: ALLOW_DEVELOPMENT_CORS_ORIGINS_POLICY,
                      policy =>
                      {
                          policy.WithOrigins(LOCAL_DEVELOPMENT_URL)
                                .AllowAnyHeader()
                                .AllowAnyMethod()
                          ;
                      });
});

//.....
app.UseCors(ALLOW_DEVELOPMENT_CORS_ORIGINS_POLICY);

```
Let's run the project
```bash
 ASPNETCORE_URLS=http://*:5001 ASPNETCORE_ENVIRONMENT=Development dotnet watch --project . run --no-launch-profile
```
and you can open `http://localhost:5001/swagger/index.html` in the browser which show swagger page.
Do not stop this project, we will use that url in api-generator.
## Step 3 : Create API-GENERATOR project
move to the root folder and jump into api_generator folder
```bash
cd ..
cd api_generator

dotnet new console -o .
dotnet add package NSwag.CodeGeneration.CSharp
dotnet add package NSwag.CodeGeneration.TypeScript
dotnet add package NSwag.Core
dotnet new gitignore
```



## Step 4 : Create Client Vite-React
using Vite to create react client project
https://vitejs.dev/guide/
```
cd client
yarn create vite . --template react-ts
```
## Step 5 : Client dotnet console App
```
mkdir client-console
cd client-console
dotnet new console -o .
dotnet add package Newtonsoft.Json
dotnet new gitignore
```
## Step 6 : Add `package.json` and add some `script` in root folder 


## Generator Project
```
mkdir api_generator
cd api_generator
dotnet new console -o .
dotnet add package NSwag.CodeGeneration.CSharp
dotnet add package NSwag.CodeGeneration.TypeScript
dotnet add package NSwag.Core
```
change `Program.cs`
```
// See https://aka.ms/new-console-template for more information
using System;
using System.IO;
using System.Threading.Tasks;
using NJsonSchema.CodeGeneration.TypeScript;
using NSwag;
using NSwag.CodeGeneration.CSharp;
using NSwag.CodeGeneration.TypeScript;

if (args.Length != 3) throw new ArgumentException("Expecting 4 arguments: URL, generatePath, language");

var url = args[0];
var generatePath = args[1];
var language = args[2];

if (language != "TypeScript" && language != "CSharp") throw new AbandonedMutexException("Invalid language parameter; valid values are TypeScript and CSharp");

var document = await OpenApiDocument.FromUrlAsync(url);
Console.WriteLine($"Generating {generatePath}...");

await System.IO.File.WriteAllTextAsync(generatePath, language switch
{
    "TypeScript" => GenerateTypeScriptClient(document),
    "CSharp" => GenerateCSharpClient(document),
    _ => throw new AbandonedMutexException("Invalid language parameter; valid values are TypeScript and CSharp")

});

static string GenerateTypeScriptClient(OpenApiDocument document)
{
    var settings = new TypeScriptClientGeneratorSettings
    {
        TypeScriptGeneratorSettings =
        {
            TypeStyle = TypeScriptTypeStyle.Interface,
            TypeScriptVersion = 3.5M,
            DateTimeType = TypeScriptDateTimeType.String
        }
    };
    var generator = new TypeScriptClientGenerator(document, settings);
    return generator.GenerateFile();
}
static string GenerateCSharpClient(OpenApiDocument document)
{
    var settings = new CSharpClientGeneratorSettings { UseBaseUrl = false };
    var generator = new CSharpClientGenerator(document, settings);
    return generator.GenerateFile();
}
```
run console app
- Generate TypeScript:
```
dotnet run --project . http://localhost:5001/swagger/v1/swagger.json ../client/clients.ts TypeScript 
```
- Generate CShrap
```
dotnet run --project . http://localhost:5001/swagger/v1/swagger.json ../client-console/clients.cs CSharp 

```
* Note: if got some errors `error CS0103: The name 'TypeScriptTypeStyle' does not exist in the current context `, please make sure you are using  `NJsonSchema.CodeGeneration.TypeScript` in Program.cs

### Install Global Package
```
npm install -g npm-run-all
```