CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/nuget-nswag

The OpenAPI/Swagger API toolchain for .NET and TypeScript

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

csharp-client-generation.mddocs/

C# Client Generation

NSwag provides powerful C# client generation capabilities that create strongly-typed HTTP clients from OpenAPI specifications. The generated clients include full type safety, async/await support, and comprehensive error handling.

CSharpClientGenerator

The main class for generating C# client code.

public class CSharpClientGenerator : ClientGeneratorBase<CSharpClientGeneratorSettings>
{
    public CSharpClientGenerator(OpenApiDocument document, CSharpClientGeneratorSettings settings);
    
    public string GenerateFile();
    public string GeneratePartialFile();
    public string GenerateContractsFile();
    public string GenerateImplementationFile();
}

CSharpClientGeneratorSettings

Comprehensive settings for C# client generation.

public class CSharpClientGeneratorSettings : ClientGeneratorBaseSettings
{
    // Class and namespace settings
    public string ClassName { get; set; }
    public string Namespace { get; set; }
    public string[] AdditionalNamespaceUsages { get; set; }
    public string ConfigurationClass { get; set; }
    
    // HTTP client settings
    public string HttpClientType { get; set; }
    public bool UseHttpClientCreationMethod { get; set; }
    public bool UseHttpRequestMessageCreationMethod { get; set; }
    public bool UseBaseUrl { get; set; }
    public bool GenerateBaseUrlProperty { get; set; }
    
    // Response handling
    public string ResponseClass { get; set; }
    public bool WrapResponses { get; set; }
    public bool WrapDtoExceptions { get; set; }
    public string ExceptionClass { get; set; }
    
    // Code generation options
    public bool GenerateOptionalParameters { get; set; }
    public bool GenerateJsonMethods { get; set; }
    public bool GenerateUpdateJsonSerializerSettingsMethod { get; set; }
    public bool UseRequestAndResponseSerializationAttribute { get; set; }
    
    // Serialization settings
    public CSharpJsonLibrary JsonLibrary { get; set; }
    public string JsonSerializerSettingsTransformationMethod { get; set; }
    public string[] JsonConverters { get; set; }
    
    // Interface generation
    public bool GenerateClientInterfaces { get; set; }
    public bool GenerateClientClasses { get; set; }
    public ClientGeneratorOutputType OutputType { get; set; }
    
    // Dependency injection
    public bool InjectHttpClient { get; set; }
    public bool DisposeHttpClient { get; set; }
    public string HttpClientBaseClass { get; set; }
    
    // Parameter handling
    public CSharpGeneratorSettings CSharpGeneratorSettings { get; set; }
    public ParameterBindingType ParameterBindingType { get; set; }
    public string ParameterDateTimeFormat { get; set; }
    public string ParameterDateFormat { get; set; }
    
    // Operation naming
    public IOperationNameGenerator OperationNameGenerator { get; set; }
}

Basic Usage

Simple Client Generation

using NSwag;
using NSwag.CodeGeneration.CSharp;

// Load OpenAPI document
var document = await OpenApiDocument.FromFileAsync("swagger.json");

// Configure settings
var settings = new CSharpClientGeneratorSettings
{
    ClassName = "ApiClient",
    Namespace = "MyApp.Clients"
};

// Generate client
var generator = new CSharpClientGenerator(document, settings);
string clientCode = generator.GenerateFile();

// Write to file
await File.WriteAllTextAsync("ApiClient.cs", clientCode);

Advanced Configuration

var settings = new CSharpClientGeneratorSettings
{
    // Basic settings
    ClassName = "MyApiClient",
    Namespace = "MyApp.HttpClients",
    
    // Use dependency injection
    InjectHttpClient = true,
    DisposeHttpClient = false,
    
    // Generate interfaces for mocking
    GenerateClientInterfaces = true,
    GenerateClientClasses = true,
    
    // Response wrapping for additional metadata
    WrapResponses = true,
    ResponseClass = "SwaggerResponse",
    
    // Exception handling
    WrapDtoExceptions = true,
    ExceptionClass = "ApiException",
    
    // JSON serialization
    JsonLibrary = CSharpJsonLibrary.NewtonsoftJson,
    GenerateUpdateJsonSerializerSettingsMethod = true,
    
    // Additional namespaces
    AdditionalNamespaceUsages = new[] 
    { 
        "Microsoft.Extensions.Logging",
        "System.ComponentModel.DataAnnotations"
    }
};

var generator = new CSharpClientGenerator(document, settings);
string clientCode = generator.GenerateFile();

Generated Client Features

HTTP Client Injection

When InjectHttpClient = true, the generated client accepts an HttpClient via dependency injection:

public partial class ApiClient : IApiClient
{
    private readonly HttpClient _httpClient;
    private readonly Lazy<JsonSerializerSettings> _settings;

    public ApiClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
        _settings = new Lazy<JsonSerializerSettings>(CreateSerializerSettings);
    }
}

Response Wrapping

When WrapResponses = true, methods return additional metadata:

public async Task<SwaggerResponse<User>> GetUserAsync(int id)
{
    // Generated implementation
    var response = await _httpClient.SendAsync(request);
    return new SwaggerResponse<User>(response.StatusCode, response.Headers, result);
}

Interface Generation

Generated interfaces support dependency injection and mocking:

public partial interface IApiClient
{
    Task<User> GetUserAsync(int id);
    Task<ICollection<User>> GetUsersAsync();
    Task CreateUserAsync(User user);
}

Controller Generation

NSwag also supports generating ASP.NET Core controllers from OpenAPI specifications.

CSharpControllerGenerator

public class CSharpControllerGenerator : CSharpGeneratorBase
{
    public CSharpControllerGenerator(OpenApiDocument document, CSharpControllerGeneratorSettings settings);
    
    public string GenerateFile();
    public string GenerateFileWithNamespace();
}

CSharpControllerGeneratorSettings

public class CSharpControllerGeneratorSettings : CSharpGeneratorSettings
{
    public string ClassName { get; set; }
    public string Namespace { get; set; }
    public CSharpControllerTarget ControllerTarget { get; set; }
    public CSharpControllerStyle ControllerStyle { get; set; }
    public CSharpControllerRouteNamingStrategy RouteNamingStrategy { get; set; }
    public string ControllerBaseClass { get; set; }
    public bool UseActionResultType { get; set; }
    public bool GenerateModelValidationAttributes { get; set; }
    public IOperationNameGenerator OperationNameGenerator { get; set; }
}

Controller Generation Example

var settings = new CSharpControllerGeneratorSettings
{
    ClassName = "UsersController",
    Namespace = "MyApp.Controllers",
    ControllerTarget = CSharpControllerTarget.AspNetCore,
    ControllerStyle = CSharpControllerStyle.Partial,
    UseActionResultType = true,
    GenerateModelValidationAttributes = true
};

var generator = new CSharpControllerGenerator(document, settings);
string controllerCode = generator.GenerateFile();

Template Models

The generation system uses template models that can be customized for advanced scenarios.

CSharpClientTemplateModel

public class CSharpClientTemplateModel : CSharpTemplateModelBase
{
    public string Namespace { get; }
    public string ClassName { get; }
    public bool HasOperations { get; }
    public bool HasBaseUrl { get; }
    public bool GenerateClientInterfaces { get; }
    public bool GenerateImplementation { get; }
    public IEnumerable<CSharpOperationModel> Operations { get; }
    public string BaseUrl { get; }
    public string ExceptionClass { get; }
}

CSharpOperationModel

public class CSharpOperationModel : OperationModelBase<CSharpParameterModel, CSharpResponseModel>
{
    public string MethodName { get; }
    public string HttpMethod { get; }
    public string Path { get; }
    public string Summary { get; }
    public string Description { get; }
    public bool IsDeprecated { get; }
    public IEnumerable<CSharpParameterModel> Parameters { get; }
    public CSharpResponseModel SuccessResponse { get; }
    public IEnumerable<CSharpResponseModel> Responses { get; }
}

CSharpParameterModel

public class CSharpParameterModel : ParameterModelBase
{
    public string Name { get; }
    public string VariableName { get; }
    public string Type { get; }
    public string Description { get; }
    public bool IsRequired { get; }
    public bool IsNullable { get; }
    public bool IsOptional { get; }
    public OpenApiParameterKind Kind { get; }
}

Enumerations

CSharpJsonLibrary

public enum CSharpJsonLibrary
{
    NewtonsoftJson,
    SystemTextJson
}

CSharpControllerTarget

public enum CSharpControllerTarget
{
    AspNetCore
}

CSharpControllerStyle

public enum CSharpControllerStyle
{
    Partial,
    Abstract
}

CSharpControllerRouteNamingStrategy

public enum CSharpControllerRouteNamingStrategy
{
    None,
    OperationId
}

ClientGeneratorOutputType

public enum ClientGeneratorOutputType
{
    Class,
    Implementation,
    Contracts
}

Advanced Scenarios

Custom Operation Name Generation

public class CustomOperationNameGenerator : IOperationNameGenerator
{
    public string GetClientName(OpenApiDocument document, string path, string httpMethod, OpenApiOperation operation)
    {
        return operation.Tags?.FirstOrDefault() ?? "Client";
    }

    public string GetOperationName(OpenApiDocument document, string path, string httpMethod, OpenApiOperation operation)
    {
        return operation.OperationId ?? $"{httpMethod}_{path.Replace("/", "_")}";
    }
}

settings.OperationNameGenerator = new CustomOperationNameGenerator();

Multiple Client Generation

// Generate separate clients for different tags
var settings = new CSharpClientGeneratorSettings
{
    OperationNameGenerator = new MultipleClientsFromFirstTagAndOperationIdGenerator(),
    GenerateClientInterfaces = true
};

var generator = new CSharpClientGenerator(document, settings);
string clientsCode = generator.GenerateFile();

Partial File Generation

// Generate only contracts (interfaces and DTOs)
var contractsCode = generator.GenerateContractsFile();

// Generate only implementation
var implementationCode = generator.GenerateImplementationFile();

// Generate partial file for customization
var partialCode = generator.GeneratePartialFile();

docs

annotations.md

aspnetcore-integration.md

cli-commands.md

core-document-model.md

csharp-client-generation.md

document-generation.md

index.md

typescript-client-generation.md

tile.json