Geren generates typed HttpClient clients from OpenAPI .json files (MSBuild AdditionalFiles) at compile time.
It ships as a Roslyn source generator (analyzer), so it runs during dotnet build and produces .g.cs files.
Geren.OpenApiClientGenerator- The source generator (as
analyzers/dotnet/cs/Geren.Client.Generator.dll).
- The source generator (as
Geren.OpenApi.Server- Server-side OpenAPI helpers: schema transformers for
x-compileandx-metadata.
- Server-side OpenAPI helpers: schema transformers for
Geren.Server.Exporter- Exporter scans the project and builds a Geren JSON specification using the Minimal API.
docs\FORMAT.mddocs\GENERATOR-DESIGN.mddocs\EXPORTER-DESIGN.md
See samples/README.md for an end-to-end sample (server generates OpenAPI JSON, Blazor WebAssembly client consumes it via AdditionalFiles and generates typed clients).
- Add packages:
dotnet add package Geren.OpenApi.Server
dotnet add package Microsoft.Extensions.ApiDescription.Server- Configure OpenAPI output (example):
<PropertyGroup>
<OpenApiDocumentsDirectory>..</OpenApiDocumentsDirectory>
<OpenApiGenerateDocumentsOptions>--file-name my-open-api</OpenApiGenerateDocumentsOptions>
</PropertyGroup>- Wire it up in
Program.cs:
builder.Services.AddOpenApi(options => options.AddSchemaTransformer<Geren.Server.Transformer>());- Add your OpenAPI JSON file as an
AdditionalFilesitem:
<ItemGroup>
<AdditionalFiles Include="..\my-open-api.json" Geren="openapi" />
</ItemGroup>- Add the generator package:
dotnet add package Geren.OpenApiClientGenerator- Build once:
dotnet build. Geren will generate:
- A shared
FactoryBridgehelper. - A
...Extensionstype withAddGerenClients(...). - Typed client classes.
By default the root namespace is Geren. You can override it:
<PropertyGroup>
<Geren_RootNamespace>MyCompany.Generated</Geren_RootNamespace>
</PropertyGroup>Note: if you reference the generator via ProjectReference/manual <Analyzer Include=...>, you may also need:
<ItemGroup>
<CompilerVisibleProperty Include="Geren_RootNamespace" />
</ItemGroup>Default JSON behavior uses JsonSerializerDefaults.Web.
To customize JSON and outgoing requests for all generated clients, implement partial hooks once:
using System.Net.Http;
using System.Text.Json;
namespace MyCompany.Generated;
public abstract partial class GerenClientBase
{
static partial void OnConfigureJsonSerializerOptions(JsonSerializerOptions options)
{
options.PropertyNameCaseInsensitive = true;
}
static partial void OnPrepareRequest(HttpRequestMessage request)
{
request.Headers.Add("X-Client", "value");
}
}If you see CS9137 related to Microsoft.AspNetCore.OpenApi.SourceGenerators, add:
<PropertyGroup>
<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated</InterceptorsNamespaces>
</PropertyGroup>- Input files:
AdditionalFileswithGeren="openapi"orGeren="gerenapi". - The generator emits client classes, one
Extensionstype, and one sharedFactoryBridgehelper per OpenAPI file.
- Namespace suffix is derived from the OpenAPI file name (without extension), sanitized by
ToLetterOrDigitName. - Final namespace is
{RootNamespace}.{NamespaceFromFileName}.{NamespaceFromSections}. - Path sections used for naming exclude template segments (
{...}).
Path to class/method mapping:
- method name:
operationId ?? (methodHttp + last section). - class name:
penultimate section + "Http" or RootHttp. - namespace:
remaining sections - Duplicate generated key
{SpaceName}.{ClassName}.{MethodName}producesGEREN006and the endpoint is skipped.
GEREN001JSON read failed (Warning)GEREN002OpenAPI parse failed (Error)GEREN003Unsupported parameter location (Error)GEREN004Unsupported query parameter type (Warning)GEREN005Unsupported request body (Error)GEREN006Duplicate generated method name (Error)GEREN007Unresolved schema reference (Error)GEREN008Missing parameter location (Error)GEREN014Ambiguous schema reference (Error)GEREN015Path placeholder and parameter name mismatch (Error)
Geren.Server.Exporter is a dotnet tool that exports *.gerenapi.json from an ASP.NET Core Minimal API server project (without running it).
See src\Geren.Server.Exporter\README.md and docs\EXPORTER-DESIGN.md.