or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

annotations.mdaspnetcore-integration.mdcli-commands.mdcore-document-model.mdcsharp-client-generation.mddocument-generation.mdindex.mdtypescript-client-generation.md
tile.json

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();