Universal.CodeGeneration.CSharp
1.4.1
See the version list below for details.
dotnet add package Universal.CodeGeneration.CSharp --version 1.4.1
NuGet\Install-Package Universal.CodeGeneration.CSharp -Version 1.4.1
<PackageReference Include="Universal.CodeGeneration.CSharp" Version="1.4.1" />
<PackageVersion Include="Universal.CodeGeneration.CSharp" Version="1.4.1" />
<PackageReference Include="Universal.CodeGeneration.CSharp" />
paket add Universal.CodeGeneration.CSharp --version 1.4.1
#r "nuget: Universal.CodeGeneration.CSharp, 1.4.1"
#:package Universal.CodeGeneration.CSharp@1.4.1
#addin nuget:?package=Universal.CodeGeneration.CSharp&version=1.4.1
#tool nuget:?package=Universal.CodeGeneration.CSharp&version=1.4.1
Universal.CodeGeneration.CSharp
A library for generating C# source code from various specifications, specializing in strongly-typed HTTP clients and URI builders.
Classes
HttpServiceClientGenerator
Generates complete, strongly-typed HTTP service client code from API specifications (such as OpenAPI/Swagger). It handles the generation of methods, request/response models, enums, and hierarchical resource navigation.
// Parse the OpenAPI JSON
string json = File.ReadAllText("openapi.json");
var spec = HttpServiceClientGenerator.ApiSpecification.FromOpenApi(json);
// Configure generation options
var options = new HttpServiceClientGenerator.Options
{
BaseClass = HttpServiceClientGenerator.BaseClientType.JsonHttpServiceClient,
GenerateModelClasses = true,
UseHierarchicalResources = true,
JsonSerializer = HttpServiceClientGenerator.JsonSerializerType.SystemTextJson
};
// Generate the code
var generator = new HttpServiceClientGenerator("MyApi.Client", "ApiClient", options);
string sourceCode = generator.Generate(spec);
Target framework compatibility
By default the generated client targets the latest BCL surface (using overloads that accept a
CancellationToken, such as HttpContent.ReadAsStringAsync(CancellationToken)). Set TargetFramework
to a target framework moniker when the generated code must compile against an older target — including
.NET Standard and .NET Framework, where those overloads do not exist:
var options = new HttpServiceClientGenerator.Options
{
BaseClass = HttpServiceClientGenerator.BaseClientType.JsonHttpServiceClient,
// e.g. "net10.0", "netstandard2.1", "netstandard2.0", "netcoreapp3.1", "net48"
TargetFramework = "netstandard2.0"
};
The moniker is resolved to BCL capability flags internally. Targets below .NET 5 (all netstandard*,
netcoreapp*, and .NET Framework monikers) omit the newer CancellationToken overloads; net5.0 and
later use them. A null, empty, or unrecognized value means "latest" and emits the newest API surface, so
it automatically tracks future .NET versions without a code change.
Client style
ClientStyle selects how operations are surfaced (it overrides UseHierarchicalResources when set):
HierarchicalResources— nested resource classes mirroring the URL tree (client.Folders[id].Items.GetAsync()).FlatBuilders— one builder per path off the client (client.FetchFolder.GetAsync()).Simple— every operation as a method directly on the client, named from the operationId. Best for flat, RPC-style APIs:
var options = new HttpServiceClientGenerator.Options
{
ClientStyle = HttpServiceClientGenerator.ClientStyle.Simple
};
// Generated (methods on the client itself; path params become method parameters):
var client = new KoncileClient();
var folder = await client.FetchFolderAsync(new FetchFolderQueryParams { FolderId = 42 });
var created = await client.CreateFolderAsync(new ConfigApiCreate { Name = "Invoices" });
await client.UploadDatatableCsvAsync<object>(agentId: 123, request: csv);
When ClientStyle is null, the style falls back to UseHierarchicalResources
(true → HierarchicalResources, false → FlatBuilders).
Base URI and constructors
The generated client's constructor takes a Uri. Set DefaultBaseUrl to also emit a DefaultBaseUri
constant and a parameterless constructor, so callers can use the client without restating the base URI
(and without hand-writing a constructor in a partial):
var options = new HttpServiceClientGenerator.Options
{
DefaultBaseUrl = "https://api.example.com/v1"
};
// Generated:
public const string DefaultBaseUri = "https://api.example.com/v1";
public ApiClient() : this(new Uri(DefaultBaseUri)) { }
public ApiClient(Uri baseUri) { /* ... */ }
// Usage:
var client = new ApiClient(); // uses DefaultBaseUri
var staging = new ApiClient(new Uri("https://staging.example.com/v1"));
When DefaultBaseUrl is null, only the Uri constructor is emitted.
OpenAPI 3.1 nullable composition
OpenAPI 3.1 expresses nullable/optional schemas as anyOf (or oneOf) with a {"type":"null"} member,
or as a type array such as ["integer","null"], rather than the 3.0 nullable: true keyword. The parser
unwraps these to the underlying type, so an optional integer query parameter becomes int?, an optional
$ref becomes the referenced type, and a property like {"anyOf":[{"type":"string"},{"type":"null"}]}
becomes a nullable string — instead of falling back to string/object.
Responses without a schema
When an operation's success response has no usable schema (e.g. an empty {}), the generated method
returns Task<HttpResponseMessage> so the caller gets the raw response (status, headers) — rather than a
forced generic Task<T>. This is consistent across all client styles. Operations with a typed response
return Task<TheType>, and array responses return the mapped collection type.
Nullable reference types
By default the generated file opts into the nullable annotation context (so emitted annotations such as
string? are valid even though generated files do not inherit the consuming project's nullable context)
while keeping nullable warnings off, so the generated code never surfaces warnings in the consumer:
#nullable enable annotations
#nullable disable warnings
Set NullableReferenceTypes = false to omit both the directives and the reference-type ? annotations —
useful for projects that disable nullable reference types or target older C# versions. Nullable value
types (e.g. int? for an optional integer query parameter) are always emitted regardless of the setting:
var options = new HttpServiceClientGenerator.Options
{
NullableReferenceTypes = false
};
Required value-type query parameters are appended to the query string unconditionally (rather than behind
an always-true != null check), so the generated code is free of "expression is always true" warnings.
String enums
OpenAPI type: string enums are emitted as integer-backed C# enums (C# enums cannot be string-backed).
Each member keeps its original wire value via a [System.Runtime.Serialization.EnumMember] attribute,
and the enum is decorated with a string-enum converter matching the configured JsonSerializer
(StringEnumConverter for Newtonsoft.Json, JsonStringEnumConverter for System.Text.Json) so values
round-trip correctly. Values containing spaces or other invalid identifier characters are sanitized into
valid PascalCase member names — e.g. "IN PROGRESS" becomes InProgress:
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum TaskStatus
{
[System.Runtime.Serialization.EnumMember(Value = "IN PROGRESS")]
InProgress = 0,
[System.Runtime.Serialization.EnumMember(Value = "DONE")]
DONE = 1
}
UriBuilderGenerator
Generates strongly-typed UriBuilder code from route definitions. This allows for type-safe URL construction based on defined API paths, supporting both fluent and flat API styles.
// Define routes manually or parse from OpenAPI
var routes = new List<UriBuilderGenerator.ApiRoute>
{
new UriBuilderGenerator.ApiRoute { Path = "users/{userId:int}/orders" },
new UriBuilderGenerator.ApiRoute { Path = "products/{category}/{id}" }
};
var options = new UriBuilderGenerator.Options
{
UseFluentGeneration = true,
FluentOptions = new UriBuilderGenerator.FluentGenerationOptions
{
UseNestedNamespaces = true,
CollapseIdMethods = true
}
};
var generator = new UriBuilderGenerator("MyNamespace", "MyApiRoutes", options);
string sourceCode = generator.Generate(routes);
ObjectExtensions
Extensions for converting runtime objects into their C# code initialization string representation. Useful for meta-programming and generating code that initializes objects with specific states.
// Simple types
int number = 42;
string numberCode = number.ToInitializerString(); // "42"
// Collections
var list = new List<string> { "A", "B" };
string listCode = list.ToInitializerString();
// "new List<string>() { "A", "B" }"
// Complex objects
var data = new { Id = 1, CreatedAt = DateTime.Now };
string objectCode = data.ToInitializerString();
// Generates object initialization syntax recursively
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 10.0.9)
- Universal.Common.Reflection (>= 2.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.5.1 | 22 | 6/17/2026 |
| 1.5.0 | 34 | 6/17/2026 |
| 1.4.1 | 30 | 6/17/2026 |
| 1.4.0 | 32 | 6/17/2026 |
| 1.3.1 | 26 | 6/17/2026 |
| 1.3.0 | 33 | 6/17/2026 |
| 1.2.0 | 119 | 3/20/2026 |
| 1.1.1 | 476 | 12/9/2025 |
| 1.1.0 | 468 | 12/9/2025 |
| 1.0.0 | 393 | 12/8/2025 |
| 0.3.0 | 635 | 5/22/2021 |
| 0.2.1 | 567 | 2/1/2021 |
| 0.2.0 | 573 | 1/5/2021 |
| 0.1.0.1 | 806 | 3/21/2019 |
| 0.1.0 | 779 | 3/21/2019 |
Fixed nullability of generated enum properties.