BonyadCode.Resulter.AspNetCore
1.1.1
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package BonyadCode.Resulter.AspNetCore --version 1.1.1
NuGet\Install-Package BonyadCode.Resulter.AspNetCore -Version 1.1.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BonyadCode.Resulter.AspNetCore" Version="1.1.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BonyadCode.Resulter.AspNetCore" Version="1.1.1" />
<PackageReference Include="BonyadCode.Resulter.AspNetCore" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BonyadCode.Resulter.AspNetCore --version 1.1.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: BonyadCode.Resulter.AspNetCore, 1.1.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=BonyadCode.Resulter.AspNetCore&version=1.1.1
#tool nuget:?package=BonyadCode.Resulter.AspNetCore&version=1.1.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
In the name of God
BonyadCode.Resulter.AspNetCore
A utility library to standardize API responses in ASP.NET Core. It supports both Controllers and Minimal APIs with consistent handling of success, failure, validation errors, and exceptions, using rich ProblemDetails following RFC7807.
โจ Features
- Unified Result Model: Consistent
ResultBuilder<T>
andResultBuilder
for all HTTP outcomes. - Support for Minimal APIs & Controllers: Seamlessly convert to
IActionResult
orIResult
. - ProblemDetails Integration: Built-in helpers to enrich error responses with metadata.
- Zero Boilerplate: Clean, expressive syntax that reduces repetitive response code.
- Validation: and Error Support: Maps errors from FluentValidation, DataAnnotations, and IdentityResult into structured responses.
๐ฆ Installation
dotnet add package BonyadCode.Resulter.AspNetCore
๐ Quick Examples
โ Success (Controller)
[HttpGet("hello")]
public IActionResult GetHello()
{
var result = ResultBuilder<string>.Success("Hello, world!");
return result.ToHttpResultController();
}
Response JSON:
{
"succeeded": true,
"statusCode": 200,
"data": "Hello, world!",
"problemDetails": null
}
โ Success (Minimal Api)
app.MapGet("/hello", () =>
{
var result = ResultBuilder<string>.Success("Hello, world!");
return result.ToHttpResultMinimal();
});
Response JSON:
{
"succeeded": true,
"statusCode": 200,
"data": "Hello, world!",
"problemDetails": null
}
โ Custom Success (Controller)
[HttpGet("hello")]
public IActionResult GetHello()
{
var result = ResultBuilder.Success("User was Created", HttpStatusCode.Created);
return result.ToHttpResultController();
}
Response JSON:
{
"succeeded": true,
"statusCode": 201,
"data": "User was Created",
"problemDetails": null
}
โ Custom Success (Minimal Api)
app.MapGet("/hello", () =>
{
var result = ResultBuilder.Success("User was Created", HttpStatusCode.Created);
return result.ToHttpResultMinimal();
});
Response JSON:
{
"succeeded": true,
"statusCode": 201,
"data": "User was Created",
"problemDetails": null
}
โ Validation Failure (Controller)
[HttpPost("register")]
public IActionResult RegisterUser(UserDto dto)
{
var result = ResultBuilder<string>.Failure()
.AddProblemDetailsFromKeyValuePairs("Email", "Email is required.")
.AddProblemDetailsFromKeyValuePairs("Password", "Password must be at least 8 characters." );
return result.ToHttpResultController();
}
or
[HttpPost("register")]
public IActionResult RegisterUser(UserDto dto)
{
var result = ResultBuilder<string>.Failure()
.AddProblemDetailsFromKeyValuePairs(["Email","Password"], ["Email is required.","Password must be at least 8 characters." ]);
return result.ToHttpResultController();
}
Response JSON:
{
"succeeded": false,
"statusCode": 400,
"data": null,
"problemDetails": {
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "A problem occurred.",
"detail": "A problem occurred (400 BadRequest).",
"status": 400,
"extensions": {
"Email": [
"Email is required."
],
"Password": [
"Password must be at least 8 characters."
]
}
}
}
๐ Minimal API Usage
โ Success
app.MapGet("/status", () =>
{
var result = ResultBuilder<string>.Success("All systems operational.", HttpStatusCode.NoContent);
return result.ToHttpResultMinimal();
});
or
app.MapGet("/status", () =>
{
var result = ResultBuilder<string>.Success("All systems operational.");
return result.ToHttpResultMinimal(HttpStatusCode.NoContent);
});
Response JSON:
{
"succeeded": true,
"statusCode": 204,
"data": "All systems operational.",
"problemDetails": null
}
โ FluentValidation Errors
app.MapPost("/login", (LoginRequest request, HttpContext? httpContext, IValidator<LoginRequest> validator) =>
{
var validationResult = validator.Validate(request);
if(!validationResult.Succeeded)
{
var result = ResultBuilder<string>.Failure()
.AddProblemDetailsFromFluentValidationResult(validationResult);
return result.ToHttpResultMinimal(HttpStatusCode.Conflict, httpContext);
}
return ResultBuilder<string>.Success("Logged in").ToHttpResultMinimal();
});
Response JSON:
{
"succeeded": false,
"statusCode": 409,
"data": null,
"problemDetails": {
"type": "https://example.com/problems/validation",
"title": "A validation problem occurred.",
"detail": "One or more validation failures occured.",
"status": 409,
"instance": "/api/register",
"extensions": {
"Username": [
"Username already exists."
]
}
}
}
โ๏ธ Custom ProblemDetails Examples
๐ ๏ธ Attach Custom Metadata
var result = ResultBuilder<string>.Failure()
.AddCustomProblemDetails(
type: "https://example.com/problems/validation",
title: "A custom problem occurred.",
details: "One or more custom failures occured.",
statusCode: HttpStatusCode.Conflict,
instance: "/api/register",
extensions: new Dictionary<string, object?>
{
{ "Username", new[] { "Username already exists." } }
}).ToHttpResultMinimal(HttpStatusCode.Conflict, httpContext);
Note: You can pass the httpContext to the above method so that "instance" is extracted automatically from it.
Response JSON:
{
"succeeded": false,
"statusCode": 409,
"data": null,
"problemDetails": {
"type": "https://example.com/problems/validation",
"title": "A custom problem occurred.",
"detail": "One or more custom failures occured.",
"status": 409,
"instance": "/api/register",
"extensions": {
"Username": [
"Username already exists."
]
}
}
}
๐ง Validation Sources
๐ง DataAnnotations
var validationResult = new ValidationResult("Email", new[] { "Invalid email" });
var result = ResultBuilder.Failure()
.AddProblemDetailsFromValidationResult(validationResult);
๐งช FluentValidation
var result = ResultBuilder.Failure()
.AddProblemDetailsFromFluentValidationResult(validationResult);
๐ IdentityResult
var result = ResultBuilder.Failure()
.AddProblemDetailsFromIdentityError(identityResult);
๐ฅ Exception Handling
try
{
throw new InvalidOperationException("Something broke.");
}
catch (Exception ex)
{
var result = ResultBuilder.Failure()
.AddProblemDetailsFromException(ex, httpContext);
return result.ToHttpResultController();
}
Response JSON (truncated):
{
"succeeded": false,
"statusCode": 500,
"data": null,
"problemDetails": {
"type": "https://tools.ietf.org/html/rfc7231#section-6.6.1",
"title": "A Server problem occurred.",
"detail": {
"message": "Something broke."
},
"status": 500,
"instance": "/api/failing-endpoint",
"extensions": {
"Message": [
"Something broke."
],
"Source": [
"MyApp"
]
}
}
}
๐ Extension Reference
Endpoint Result Methods:
Method | Description |
---|---|
ToHttpResultController() |
returns an IActionResult result for use in Controllers |
ToHttpResultController(...) |
returns an IActionResult result for use in Controllers (accepting parameters) |
ToHttpResultMinimal() |
returns an IResult result for use in Minimal |
ToHttpResultMinimal(...) |
returns an IResult result for use in Minimal APIs (accepting parameters) |
ProblemDetails Helper Methods:
Method | Description |
---|---|
AddSimpleProblemDetails() |
Attaches default problem info |
AddCustomProblemDetails(...) |
Fully customized metadata |
AddProblemDetailsFromException(...) |
Adds public exception properties |
AddProblemDetailsFromIdentityError(...) |
Maps IdentityResult errors |
AddProblemDetailsFromFluentValidationResult(...) |
Maps FluentValidation errors |
AddProblemDetailsFromValidationResult(...) |
Maps DataAnnotation errors |
AddProblemDetailsFromKeyValuePairs(...) |
Adds custom errors by key/value(s) |
๐งช API Behavior Matrix
Scenario | Method | Status Code | Description |
---|---|---|---|
Success | ResultBuilder.Success() |
Any (Default: 200 OK) | Standard success with optional data |
Failure | ResultBuilder.Failure() |
Any (Default: 400 Bad Request) | Standard failure with optional data (exception, validation, etc.) |
Create | ResultBuilder.Create() |
Any | User-defined structured error response |
๐ค Contributing
PRs and feedback welcome! GitHub โ
๐ License
Apache 2.0 โ see the LICENSE file.
๐ฆ Links
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 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- FluentValidation (>= 12.0.0)
- Newtonsoft.Json (>= 13.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.