Kanject.Core.Api.Abstractions
3.10.0
Prefix Reserved
dotnet add package Kanject.Core.Api.Abstractions --version 3.10.0
NuGet\Install-Package Kanject.Core.Api.Abstractions -Version 3.10.0
<PackageReference Include="Kanject.Core.Api.Abstractions" Version="3.10.0" />
<PackageVersion Include="Kanject.Core.Api.Abstractions" Version="3.10.0" />
<PackageReference Include="Kanject.Core.Api.Abstractions" />
paket add Kanject.Core.Api.Abstractions --version 3.10.0
#r "nuget: Kanject.Core.Api.Abstractions, 3.10.0"
#:package Kanject.Core.Api.Abstractions@3.10.0
#addin nuget:?package=Kanject.Core.Api.Abstractions&version=3.10.0
#tool nuget:?package=Kanject.Core.Api.Abstractions&version=3.10.0
Kanject.Core.Api.Abstractions
Kanject.Core.Api.Abstractions holds the contract types shared by Kanject ASP.NET Core services and their service layers: the JSON response envelope and pagination models, the ApiResponseCode vocabulary, ApiServiceException, minimal-API result helpers, FluentValidation rules with XSS screening, and the identity interfaces the controller helpers build on.
Reference it directly from class libraries (services, validators, endpoint modules) that must speak the same response and error language as the web host without depending on a specific edge package. Kanject.Core.Api and Kanject.Core.ApiV2 both reference it, so web projects using either get it transitively.
Installation
dotnet add package Kanject.Core.Api.Abstractions
Targets .NET 8, .NET 9 and .NET 10, and is marked Native AOT / trimming compatible. It depends on Kanject.Core and FluentValidation, and uses ASP.NET Core types (IResult, ModelStateDictionary), so it is intended for ASP.NET Core applications and the libraries they call.
Quick start
A minimal-API endpoint that returns the standard envelope and signals an expected failure:
using Kanject.Core.Api.Abstractions.Endpoints;
using Kanject.Core.Api.Abstractions.Enums;
using Kanject.Core.Api.Abstractions.Exceptions;
using Kanject.Core.Api.Abstractions.Models;
app.MapGet("/api/orders/{id:guid}", async (Guid id, IOrderStore store, CancellationToken ct) =>
{
var order = await store.FindAsync(id, ct)
?? throw new ApiServiceException("id", "The order does not exist.", ApiResponseCode.NotFound);
return order.ApiResponse("Order retrieved.");
});
app.MapGet("/api/orders", async (int pageSize, string? pageToken, IOrderStore store, CancellationToken ct) =>
{
var page = await store.ListAsync(pageSize, pageToken, ct);
var metadata = new PayloadMetadata(pageSize, page.Items.Count, pageToken: page.NextToken);
return page.Items.ApiResponse(metadata);
});
This package defines ApiServiceException but does not translate it into an HTTP response. The exception middleware in Kanject.Core.Api (Kanject envelope) or Kanject.Core.ApiV2 (Problem Details) does that; without one of them, register your own handler.
The response envelope
ResponseBase<T> / Response<T> serialize as:
{
"data": { "id": "3f2c…" },
"message": "Order retrieved.",
"responseCode": "0",
"status": 200
}
| Factory | responseCode (unless you pass one) |
status |
|---|---|---|
Response<T>.Success(data, message, responseCode) |
"0" (Success); message defaults to "Success" |
200 |
Response<T>.Failed(errorMessage, responseCode) |
"1" (Error) |
400 |
Response<T>.Warning(warningMessage, data, responseCode) |
"3" (Warning) |
400 |
responseCode is a business code carried as a string — the numeric value of an ApiResponseCode by default, or any code you supply. status is a body field; the HTTP status of the response is set separately by whoever writes it (Results.Ok, a controller helper, the exception middleware).
Pagination
PayloadMetadata(readonly struct) —PageSize,PageItemCount,PageToken,HasNextPage,Custom. The constructor setsHasNextPage = truewheneverpageTokenis non-empty (and not"{}"), so passing the continuation token is enough.PayloadMetadata.CreateEmpty(pageSize, pageToken)builds an empty page.ApiResponseDataset<T>— what paginated responses put indata:Dataset,PageSize,PageItemCount,PageToken,HasNextPage,Custom.PaginatedQueryModel— base class for requests withpageSize/pageToken.
Response codes
ApiResponseCode (namespace Kanject.Core.Api.Abstractions.Enums) is the shared business-code vocabulary. The value in responseCode is the member's number:
| Code | Member | Code | Member |
|---|---|---|---|
| 0 | Success |
8 | BadRequest |
| 1 | Error |
9 | InternalServerError |
| 2 | ValidationError |
10 | ServiceUnavailable |
| 3 | Warning |
11 | TooManyRequests |
| 4 | Unauthorized |
12 | Created |
| 5 | NotFound |
13 | Accepted |
| 6 | Forbidden |
14 | NoContent |
| 7 | Conflict |
The HTTP status an edge package assigns is its own mapping — the exception middleware in Kanject.Core.Api / Kanject.Core.ApiV2 maps ValidationError → 400, Unauthorized → 401, NotFound → 404, Success → 200, and everything else → 500.
Exceptions
| Constructor | Use |
|---|---|
ApiServiceException(key, message, apiResponseCode = ApiResponseCode.ValidationError) |
Expected failure tied to a field or concept (key becomes the validation key) |
ApiServiceException(message, responseCode, exception = null) |
Expected failure with an explicit code |
ApiServiceException(message) / (message, innerException) |
Generic failure (Error) |
ApiValidationException(message, key = "model") |
Shorthand for a ValidationError |
ExceptionKey and ResponseCode are exposed as properties for custom middleware.
Minimal-API helpers
Namespace Kanject.Core.Api.Abstractions.Endpoints — extension methods returning IResult:
| Extension | Result |
|---|---|
payload.ApiResponse(message, responseCode) |
200 with the success envelope |
items.ApiResponse(metadata, message, responseCode) |
200 with an ApiResponseDataset<T> envelope |
validationResults.ApiErrorResponse() |
400 envelope from IEnumerable<ValidationResult>; message is the first error |
modelState.ApiErrorResponse() |
400 envelope from a ModelStateDictionary; message is the first error |
modelState.ValidationErrorList() |
The same envelope as a Response<IEnumerable<string>> value (not an IResult) |
modelState.ValidationErrorString() / GetFirstValidationError() |
All messages joined with "; ", or the first message |
Namespace Kanject.Core.Api.Abstractions.Extensions adds current-user helpers on ClaimsPrincipal and HttpContext: GetCurrentUserId(), GetCurrentUserOrganizationId(), GetCurrentUserGroups() and GetCurrentUserAsync(). They resolve your IUserIdentityClaimsPrincipal through the application builder registered with app.UseAppUtilityService(...) (from Kanject.Core), in a new scope created from the root provider.
Validation
FluentValidation rule extensions in Kanject.Core.Api.Abstractions.Extensions:
using FluentValidation;
using Kanject.Core.Api.Abstractions.Enums;
using Kanject.Core.Api.Abstractions.Extensions;
public sealed record CreateOrderRequest(string CustomerName, string Email, string Notes, string CallbackUrl);
public sealed class CreateOrderRequestValidator : AbstractValidator<CreateOrderRequest>
{
public CreateOrderRequestValidator()
{
RuleFor(x => x.CustomerName).NotEmpty().MustMatchKnownNames();
RuleFor(x => x.Email).MustBeValidEmailAddress();
RuleFor(x => x.Notes).MustBeSafeFromXss(XssValidationMode.Standard, maxLength: 2000);
RuleFor(x => x.CallbackUrl).MustBeValidUrl(allowedSchemes: ["https"]);
}
}
| Rule | Checks |
|---|---|
MustBeSafeFromXss(mode, customAllowedChars, allowEmpty, maxLength, enableAdvancedDetection) |
Character allow-list for the XssValidationMode, known script/event-handler/encoding patterns, and optional template/CSS/SQL-injection heuristics. Error code XSS_VALIDATION_FAILED. |
MustBeSafeHtml(allowedTags, allowedAttributes, allowEmpty) |
HTML restricted to an allow-list of tags and attributes. Error code UNSAFE_HTML_CONTENT. |
MustNotIncludeHarmfulXssProneCharacters(additionalAllowedChars, allowEmpty) |
Letters, digits, space and .,!?-_@, plus a limited set of extra punctuation you opt into |
MustBeValidUrl(allowedSchemes, allowEmpty) |
Absolute URL with an allowed scheme (http/https by default) and no script payloads. Error code INVALID_OR_UNSAFE_URL. |
MustMatchKnownNames() |
Letters, digits, hyphens and spaces |
MustContainOnlyAlphanumericAndSpaces() |
Letters, digits and spaces |
MustBeValidEmailAddress() |
Basic local@domain.tld format |
XssValidationMode: Strict, Standard (the default), Html, Markdown, Custom. The built-in character sets are ASCII-only and exclude line breaks, so accented letters, non-Latin scripts and multi-line text fail every mode except Custom with your own character set.
To surface FluentValidation results through MVC model state, use ModelState.TryAddValidationErrors(validationResult) — property names are camel-cased as keys. Overloads also merge another ModelStateDictionary or a ValidationProblemDetails. GetValidationErrors() joins all messages with ", ".
Service-layer and identity contracts
IService/AbstractService— a disposable service base that accumulates errors in aModelStateDictionary(Errors,HasError) alongsideResponseCode,StatusCodeandResponseMessage, for services that report failures instead of throwing.IUserIdentityClaimsPrincipal— implement it for your identity provider:GetUserId,GetUserGroups,GetUserPermissions,GetUserIdentityInformation. The current-user helpers here and inKanject.Core.Api/Kanject.Core.ApiV2call it.IApplicationUser,IApplicationUserGroup— user and group shapes returned by that reader.HttpRequestLoggerExtensions.LogHttpRequestAsync(request, exception)— prints the URL, verb, headers (exceptAuthorization), full request body, and exception details to the console. The edge packages call it for unhandled exceptions; mind personal data in bodies and cookies.
Attributes for generated minimal APIs
[ApiEndpoints] and the [HttpGet], [HttpPost], [HttpPut], [HttpDelete], [HttpPatch] attributes in Kanject.Core.Api.Abstractions.Attributes describe minimal-API endpoint groups as static classes. They do nothing on their own — add the Kanject.Core.Api.Annotations source generator to turn them into route registrations. These verb attributes are distinct from the MVC attributes of the same names in Microsoft.AspNetCore.Mvc.
Related packages
| Package | Role | Availability |
|---|---|---|
Kanject.Core.Api |
Controllers, exception middleware (Kanject envelope errors) and tenant middleware | nuget.org |
Kanject.Core.ApiV2 |
Controllers, exception middleware (Problem Details errors) and tenant middleware | nuget.org |
Kanject.Core.Api.Annotations |
Source generator and analyzers for [ApiEndpoints] classes |
nuget.org |
Kanject.Core.Api.Aws.Extensions |
Parameter Store configuration and CloudWatch-friendly console output | nuget.org |
Kanject.Core |
Core utilities this package builds on, including UseAppUtilityService |
nuget.org |
License
Licensed under the Kanject Code Libraries License Agreement (KCLLA); the full text ships in this package as LICENSE.md. Organizations whose trailing-twelve-month gross revenue and total funding raised are each below US$250,000 may use it at no cost under the Free Tier. At or above either threshold a commercial license is required — contact commercial@kanjectbusiness.com.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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 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
- FluentValidation (>= 12.1.1)
- Kanject.Core (>= 3.14.0)
-
net8.0
- FluentValidation (>= 12.1.1)
- Kanject.Core (>= 3.14.0)
-
net9.0
- FluentValidation (>= 12.1.1)
- Kanject.Core (>= 3.14.0)
NuGet packages (5)
Showing the top 5 NuGet packages that depend on Kanject.Core.Api.Abstractions:
| Package | Downloads |
|---|---|
|
Kanject.Core.Adapter
Kanject service adapter library |
|
|
Kanject.Core.Api.Aws.Extensions
Kanject core AWS api Extensions |
|
|
Kanject.Core.Api
Kanject core api |
|
|
Kanject.Core.Logs.Abstractions
Kanject Logs Abstractions |
|
|
Kanject.Core.ApiV2
Kanject core api V2 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.10.0 | 45 | 10/2/2026 |
| 3.9.1 | 207 | 9/27/2026 |
| 3.9.0 | 169 | 9/27/2026 |
| 3.8.7 | 163 | 9/26/2026 |
| 3.8.6 | 203 | 9/7/2026 |
| 3.8.5 | 178 | 8/27/2026 |
| 3.8.4 | 199 | 8/22/2026 |
| 3.8.3 | 203 | 8/10/2026 |
| 3.8.2 | 187 | 8/9/2026 |
| 3.8.1 | 197 | 8/5/2026 |
| 3.8.0 | 199 | 8/5/2026 |
| 3.7.0 | 206 | 8/3/2026 |
| 3.6.7 | 216 | 7/30/2026 |
| 3.6.6 | 224 | 7/18/2026 |
| 3.6.5 | 131 | 7/13/2026 |
| 3.6.4 | 223 | 7/11/2026 |
| 3.6.3 | 213 | 7/11/2026 |
| 3.6.2 | 373 | 7/9/2026 |
| 3.6.1 | 237 | 7/9/2026 |