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.
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();
}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; }
}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);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();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);
}
}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);
}Generated interfaces support dependency injection and mocking:
public partial interface IApiClient
{
Task<User> GetUserAsync(int id);
Task<ICollection<User>> GetUsersAsync();
Task CreateUserAsync(User user);
}NSwag also supports generating ASP.NET Core controllers from OpenAPI specifications.
public class CSharpControllerGenerator : CSharpGeneratorBase
{
public CSharpControllerGenerator(OpenApiDocument document, CSharpControllerGeneratorSettings settings);
public string GenerateFile();
public string GenerateFileWithNamespace();
}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; }
}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();The generation system uses template models that can be customized for advanced scenarios.
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; }
}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; }
}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; }
}public enum CSharpJsonLibrary
{
NewtonsoftJson,
SystemTextJson
}public enum CSharpControllerTarget
{
AspNetCore
}public enum CSharpControllerStyle
{
Partial,
Abstract
}public enum CSharpControllerRouteNamingStrategy
{
None,
OperationId
}public enum ClientGeneratorOutputType
{
Class,
Implementation,
Contracts
}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();// 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();// 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();