Raycynix.Extensions.Contracts.AspNetCore
3.0.0
dotnet add package Raycynix.Extensions.Contracts.AspNetCore --version 3.0.0
NuGet\Install-Package Raycynix.Extensions.Contracts.AspNetCore -Version 3.0.0
<PackageReference Include="Raycynix.Extensions.Contracts.AspNetCore" Version="3.0.0" />
<PackageVersion Include="Raycynix.Extensions.Contracts.AspNetCore" Version="3.0.0" />
<PackageReference Include="Raycynix.Extensions.Contracts.AspNetCore" />
paket add Raycynix.Extensions.Contracts.AspNetCore --version 3.0.0
#r "nuget: Raycynix.Extensions.Contracts.AspNetCore, 3.0.0"
#:package Raycynix.Extensions.Contracts.AspNetCore@3.0.0
#addin nuget:?package=Raycynix.Extensions.Contracts.AspNetCore&version=3.0.0
#tool nuget:?package=Raycynix.Extensions.Contracts.AspNetCore&version=3.0.0
Raycynix.Extensions.Contracts.AspNetCore
Raycynix.Extensions.Contracts.AspNetCore adds ASP.NET Core integration for the shared contract types defined in Raycynix.Extensions.Contracts.
Package
- Version:
3.0.0 - Target framework:
net10.0 - Built on ASP.NET Core 10.x
What it contains
- endpoint metadata for declared contract identities
- middleware for writing contract headers to HTTP responses
- helpers for reading contract headers from incoming requests
- minimal API helpers for contract-aware HTTP results
- MVC helpers for converting
ModelStateintoErrorContract - optional Microsoft.Extensions.Logging diagnostics for contract middleware and result execution
Installation
builder.Services.AddRaycynixContractsAspNetCore();
var app = builder.Build();
app.UseRaycynixContracts();
Response Shape Options
Use plain contract results when you want headers plus the original response body:
app.MapGet("/catalog/prices/{id}", (HttpContext httpContext) =>
httpContext.Contract(new Money
{
Amount = 149.99m,
Currency = "USD"
}))
.WithContract("catalog.prices", "1.2.0");
Use VersionedContract(...) when you want the body wrapped into VersionedContract<T>.
How It Works
Contract support in ASP.NET Core has two separate parts:
- endpoint metadata, which declares the contract name and version for the HTTP endpoint
- response shaping, which decides whether the body is a plain DTO or a
VersionedContract<T>
When you declare a contract on an endpoint, the middleware writes these response headers automatically:
X-Contract-NameX-Contract-Version
Use the result helpers only when you also want the response body to follow a contract-aware shape.
Minimal API
Declare contract metadata directly on the endpoint:
app.MapGet("/catalog/prices", () =>
httpContext => httpContext.VersionedContract(
new[] { new Money { Amount = 149.99m, Currency = "USD" } }))
.WithContract("catalog.prices", "1.2.0");
WithContract(...) declares the endpoint contract metadata.
httpContext.VersionedContract(...) reads that metadata from the current endpoint, wraps the response body into VersionedContract<T>, and writes the same contract headers.
Contract names must be non-empty and versions must use the major.minor.patch format. Version 3.0
validates this metadata while endpoints, attributes, and contract results are configured, rather than
silently producing a response without contract headers.
If you only need headers and a plain response body, return a regular ASP.NET Core result:
app.MapGet("/catalog/prices/{id}", () =>
TypedResults.Ok(new Money
{
Amount = 149.99m,
Currency = "USD"
}))
.WithContract("catalog.prices", "1.2.0");
MVC / Controllers
For MVC controllers or actions, use the attribute:
[ApiController]
[Route("api/catalog/prices")]
[Contract("catalog.prices", "1.2.0")]
public sealed class CatalogController : ControllerBase
{
[HttpGet("{id}")]
public IResult GetPrice(string id)
{
var payload = new Money
{
Amount = 149.99m,
Currency = "USD"
};
return this.VersionedContract(payload);
}
}
The attribute declares endpoint metadata.
The middleware reads that metadata and writes the headers.
If you return this.VersionedContract(...), the body is wrapped into VersionedContract<T> using the same endpoint metadata.
If you return Ok(payload) or another normal controller result, the middleware still writes headers as long as the endpoint has [Contract(...)].
Declaring vs Writing
- declare the contract on the endpoint:
- Minimal API:
.WithContract(...) - MVC:
[Contract(...)]
- Minimal API:
- write contract headers:
app.UseRaycynixContracts()
- choose the response body format:
- plain DTO/body: return
Ok(...),TypedResults.Ok(...), etc. - versioned envelope: return
this.VersionedContract(...)orhttpContext.VersionedContract(...)
- plain DTO/body: return
Request Header Access
Read incoming contract metadata from request headers:
if (httpContext.TryGetRequestContractMetadata(out var requestContract))
{
// apply compatibility rules here
}
Validation Errors
Convert ASP.NET Core ModelState into the shared transport error shape:
var error = ModelState.ToErrorContract(traceId: HttpContext.TraceIdentifier);
This package intentionally provides transport integration only. It does not enforce compatibility policy or automatic contract negotiation.
Logging
The package uses the standard Microsoft.Extensions.Logging.ILogger<T> abstraction when a logger is available. Logger dependencies are optional, so the package can run without registering a logging provider. It does not require Raycynix.Extensions.Serilog; any Microsoft-compatible logging provider can receive the events.
Contract metadata middleware and contract HTTP results write detailed execution diagnostics at Debug. They log contract names, versions, endpoint names, status codes, and envelope usage, but never log response payloads.
Enable Debug logs when troubleshooting contract header emission or contract result execution:
{
"Logging": {
"LogLevel": {
"Raycynix.Extensions.Contracts.AspNetCore": "Debug"
}
}
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Raycynix.Extensions.Contracts (>= 3.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v3.0.0 aligns the package with net10.0, validates contract identities when endpoints and results are configured, normalizes incoming contract names, validates ModelState error identities, and retains optional Microsoft.Extensions.Logging diagnostics.