Linger.Results.AspNetCore
1.6.2
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 Linger.Results.AspNetCore --version 1.6.2
NuGet\Install-Package Linger.Results.AspNetCore -Version 1.6.2
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="Linger.Results.AspNetCore" Version="1.6.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Linger.Results.AspNetCore" Version="1.6.2" />
<PackageReference Include="Linger.Results.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 Linger.Results.AspNetCore --version 1.6.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Linger.Results.AspNetCore, 1.6.2"
#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.
#:package Linger.Results.AspNetCore@1.6.2
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Linger.Results.AspNetCore&version=1.6.2
#tool nuget:?package=Linger.Results.AspNetCore&version=1.6.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Linger.Results.AspNetCore
Linger.Results.AspNetCore provides extension methods that seamlessly integrate the Linger.Results library with ASP.NET Core framework, allowing API controllers to easily return results in a unified format.
Features
- Elegantly convert
ResultandResult<T>objects to ASP.NET CoreActionResult - Support for Minimal API - convert
ResultandResult<T>toIResultusing modernResultsstatic class - Automatically select appropriate HTTP status codes based on result status
- Support for custom success and failure status codes
- Provide RFC 7807 standard ProblemDetails format output
Supported Framework Versions
- .NET 8.0+
Installation
dotnet add package Linger.Results.AspNetCore
Basic Usage
Using in Controllers
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
[HttpGet("{id}")]
public async Task<ActionResult<UserDto>> GetUser(int id)
{
var result = await _userService.GetUserByIdAsync(id);
return result.ToActionResult(); // Success returns UserDto, failure returns error array
}
[HttpPost]
public async Task<ActionResult<UserDto>> CreateUser(CreateUserRequest request)
{
var result = await _userService.CreateUserAsync(request);
return result.ToActionResult(HttpStatusCode.Created);
}
[HttpDelete("{id}")]
public async Task<ActionResult> DeleteUser(int id)
{
var result = await _userService.DeleteUserAsync(id);
return result.ToActionResult(HttpStatusCode.NoContent); // Success returns 204, failure returns error
}
// Compatible with methods returning IActionResult type signature
// This only applies to non-generic Result; Result<T> should use ActionResult<T>
[HttpPut("{id}")]
public async Task<IActionResult> UpdateUser(int id, UpdateUserRequest request)
{
var result = await _userService.UpdateUserAsync(id, request);
return result.ToActionResult(); // Non-generic Result can be returned directly as IActionResult
}
}
Using in Minimal API
var app = WebApplication.Create();
app.MapGet("/api/users/{id}", async (int id, IUserService userService) =>
{
var result = await userService.GetUserByIdAsync(id);
return result.ToHttpResult(); // Automatic status code mapping
});
app.MapPost("/api/users", async (CreateUserRequest request, IUserService userService) =>
{
var result = await userService.CreateUserAsync(request);
// Check IsSuccess because accessing result.Value requires the result to be successful
return result.IsSuccess
? result.ToCreatedResult($"/api/users/{result.Value.Id}")
: result.ToHttpResult(); // Failure returns ProblemDetails automatically
});
app.MapDelete("/api/users/{id}", async (int id, IUserService userService) =>
{
var result = await userService.DeleteUserAsync(id);
return result.ToNoContentResult(); // Success returns 204 No Content
});
API Method Comparison
| Scenario | Controller API | Minimal API |
|---|---|---|
| Auto status codes | result.ToActionResult() |
result.ToHttpResult() |
| Custom success code | result.ToActionResult(successStatusCode: HttpStatusCode.Created) |
result.ToHttpResult(successStatusCode: HttpStatusCode.Created) |
| Custom both codes | result.ToActionResult(HttpStatusCode.Created, HttpStatusCode.Conflict) |
result.ToHttpResult(HttpStatusCode.Created, HttpStatusCode.Conflict) |
| Specific created response | result.ToActionResult(HttpStatusCode.Created) |
result.ToCreatedResult("/api/users/123") |
| No content response | result.ToActionResult(HttpStatusCode.NoContent) |
result.ToNoContentResult() |
| Problem details | result.ToProblemDetails() |
result.ToHttpResult() (uses ProblemDetails automatically) |
When to use
- Use
ToActionResult()/ToHttpResult()for most standard CRUD operations (default auto-mapping handles status codes correctly) - Use
ToCreatedResult()for POST endpoints to return 201 Created with location header - Use
ToNoContentResult()for DELETE/PUT endpoints to return 204 No Content on success - Use
ToProblemDetails()when you explicitly need RFC 7807 Problem Details format response
Status Code Parameters:
ToActionResult()/ToActionResult<T>()/ToHttpResult()/ToHttpResult<T>(): BothsuccessStatusCodeandfailureStatusCodeare optional. When not specified,successStatusCodedefaults to 200 OK;failureStatusCodeis auto-determined byResult.Status(e.g.,NotFound→ 404, others → 400)ToProblemDetails()/ToProblemDetails<T>(): OnlyfailureStatusCodeis optional, same auto-determination applies
Response Format Examples
Success Responses
// Result<UserDto> success
{
"id": 123,
"name": "John Doe",
"email": "john.doe@example.com"
}
// Result success
{
"status": "Ok",
"isSuccess": true,
"isFailure": false,
"errors": []
}
Failure Responses
// Standard error format
[
{
"code": "User.NotFound",
"message": "User with ID 123 not found"
}
]
See detailed request/response mapping and error contract in
[REQUEST_RESPONSE_MAPPING.zh-CN.md](../Linger.HttpClient.Standard/REQUEST_RESPONSE_MAPPING.zh-CN.md).
Short summary: `errors` values are arrays of strings per field; `CreateProblemDetails` groups `Error` items by `Code` and writes `string[]` into `errors`. The client will prioritize `detail` for the global message, otherwise the first `errors` entry.
Note: `errors` is an RFC 7807 extension member and SHOULD use string arrays (e.g. `{"Field": ["msg1", "msg2"]}`) so a single field can carry multiple validation messages. The server adds it via `ProblemDetails.Extensions["errors"]`; ASP.NET Core serializes `Extensions` entries as top-level properties, so you will see a top-level `errors` field.
Client mapping notes:
- The library exposes `ProblemDetails` with `errors` where each value is an array of strings. `CreateProblemDetails` groups `Error` items by `Code` and sets each group's messages as `string[]` in `errors`.
- Consumers should expect `errors` values to be arrays and handle multiple messages per field. When using `ToProblemDetails()`, clients will receive `errors` that map to `ApiResult.Errors` where each array element becomes an `Error` item (`Error.Code` = field, `Error.Message` = single message).
## Status Code Mapping
- `Result.Success()` → 200 OK
- `Result.NotFound()` → 404 Not Found
- `Result.Failure()` → 400 Bad Request
## Best Practices
1. **Separation of Concerns**: Service layer returns `Result`, controller handles HTTP response conversion
2. **Consistent API Responses**: Maintain unified error formats across the application
3. **Use ProblemDetails**: Prefer RFC 7807 format for client-facing APIs
4. **Choose Right API Style**: Use Controllers for complex scenarios, Minimal API for simple cases
## Design Decision: Why No `IActionResult` Conversion Methods?
`ActionResult` and `ActionResult<T>` are the recommended modern approach, and we intentionally do not provide `IActionResult` conversion methods for the following reasons:
- **Type Safety**: `ActionResult<T>` is generic and preserves the complete type information of return values, facilitating framework features like OpenAPI/Swagger generation and type checking. `IActionResult` is a non-generic interface that loses generic type information, hindering tool chain support.
- **Seamless Compatibility**: Non-generic `Result` converts directly to `ActionResult`, so when your method signature needs to return `IActionResult` you can return `ToActionResult()` directly; `Result<T>` should use `ActionResult<T>` as the return type.
- **Consistency**: We follow ASP.NET Core official best practices by prioritizing the use of generic `ActionResult<T>` over non-generic `IActionResult`.
**Summary**: If your method return type is `IActionResult`, you can directly use `ToActionResult()` for non-generic `Result`; if you are returning `Result<T>`, change the method signature to `ActionResult<T>`.
## Using with Linger.Results
This library is an extension of [Linger.Results](../Linger.Results/README.md). Please also refer to the Linger.Results documentation to learn more about result object functionality.
| 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net10.0
- Linger.Results (>= 1.6.2)
-
net8.0
- Linger.Results (>= 1.6.2)
-
net9.0
- Linger.Results (>= 1.6.2)
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.6.4 | 42 | 8/16/2026 |
| 1.6.3 | 102 | 8/5/2026 |
| 1.6.2 | 114 | 8/2/2026 |
| 1.6.0 | 108 | 7/25/2026 |
| 1.5.5 | 107 | 7/23/2026 |
| 1.5.4-preview | 80 | 7/21/2026 |
| 1.5.3-preview | 96 | 7/20/2026 |
| 1.5.2-preview | 95 | 7/19/2026 |
| 1.5.1-preview | 94 | 7/15/2026 |
| 1.5.0-preview | 88 | 7/14/2026 |
| 1.4.4-preview | 108 | 6/16/2026 |
| 1.4.3-preview | 99 | 6/15/2026 |
| 1.4.2 | 118 | 5/20/2026 |
| 1.4.1-preview | 105 | 5/12/2026 |
| 1.4.0 | 111 | 5/6/2026 |
| 1.3.3-preview | 88 | 5/5/2026 |
| 1.3.2-preview | 109 | 4/29/2026 |
| 1.3.1-preview | 106 | 4/28/2026 |
| 1.3.0-preview | 104 | 4/27/2026 |
| 1.2.0-preview | 113 | 3/29/2026 |
Loading failed