Etymon.Result 1.2.0

dotnet add package Etymon.Result --version 1.2.0
                    
NuGet\Install-Package Etymon.Result -Version 1.2.0
                    
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="Etymon.Result" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Etymon.Result" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Etymon.Result" />
                    
Project file
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 Etymon.Result --version 1.2.0
                    
#r "nuget: Etymon.Result, 1.2.0"
                    
#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=Etymon.Result&version=1.2.0
                    
Install Etymon.Result as a Cake Addin
#tool nuget:?package=Etymon.Result&version=1.2.0
                    
Install Etymon.Result as a Cake Tool

Etymon.Result

Etymon.Result is a lightweight C# library for handling success and failure outcomes in a clean and structured way using the Result pattern.


πŸš€ Features

  • Unified success and failure model
  • Supports both Result<T> and Result (for void)
  • Clean functional style: Match, Deconstruct, implicit conversion
  • Supports enum-based error codes using ResultCode

πŸ“¦ Installation

dotnet add package Etymon.Result

βœ… How to Use

Step 1: Change your service return type

Change this:

Task<Model> GetItem(int id);

To:

Task<Result<Model>> GetItem(int id);

Step 2: Implement the service method

public async Task<Result<Model>> GetItem(int id)
{
    var data = await _db.Items.FirstOrDefaultAsync(i => i.Id == id);

    if (data == null)
    {
        return new Error("DataNotFound", "Item you're looking for is not available.");
        // OR (recommended from v1.2+)
        // return Result<Model>.Failure(ResultCode.NotFound, "Item you're looking for is not available.");
    }

    return data; // Implicitly converted to Result<Model>.Success(data)
}

βœ… Tip: You can use Result.Success(data) explicitly, or just return the data directly.


Step 3: Controller usage

[Route("get-item")]
[HttpGet]
public async Task<IActionResult> GetItemById(int id)
{
    var result = await _service.GetItem(id);

    if (!result.IsSuccess)
    {
        if (result.Error?.Code == "DataNotFound")
            return NotFound(result);
        else
            return BadRequest(result);
    }

    return Ok(result);
}

⚠️ If you use BadRequest(result.Error.Message) you'll lose the full error structure (see Step 4 for sample outputs).


Step 4: Output Examples

βœ… Success response:
{
  "data": {
    "id": 1,
    "itemName": "some item",
    "isActive": false
  },
  "error": null,
  "isSuccess": true
}
❌ Failure response:
{
  "data": null,
  "error": {
    "code": "DataNotFound",
    "message": "Item you're looking for is not available."
  },
  "isSuccess": false
}

πŸ”§ Update in v1.1.2 – Result without return value (void-like)

Prior to v1.1.2, Result<T> was required. Now, you can return just Result for operations that don’t return a value:

public async Task<Result> SaveItem(Item model)
{
    using var trans = await _db.Database.BeginTransactionAsync();

    try
    {
        var obj = await _db.Items.FirstOrDefaultAsync(x => x.ItemId == model.ItemId) ?? new Item();

        obj.Title = model.Title;

        _db.Entry(obj).State = obj.ItemId > 0 ? EntityState.Modified : EntityState.Added;

        await _db.SaveChangesAsync();
        await trans.CommitAsync();

        return Result.Success();
    }
    catch (Exception ex)
    {
        await trans.RollbackAsync();
        return Result.Failure(new Error("UnrecognisedError", "Something went wrong!"));
    }
}

πŸ†• Update in v1.2.0 – Enum-based Error Support

In version 1.2.0, we've added support for ResultCode enum for standardized error handling.

You can now create errors like this:

return Result<Model>.Failure(ResultCode.NotFound, "Item not found.");

This allows you to use consistent and meaningful codes instead of free-form strings, making controller mapping and API responses cleaner.


🧱 Built-in ResultCode Enum

public enum ResultCode
{
    Success,
    NotFound,
    ValidationError,
    Unauthorized,
    Conflict,
    InternalError
}

The Error class now supports both string-based and enum-based codes.

✨ Extension Package: Etymon.Result.Extensions

For cleaner controller code and automatic HTTP status mapping, install the optional extensions package:

dotnet add package Etymon.Result.Extensions

Then use the ToActionResult() helper in your controller:

using Etymon.Result.Extensions;

[HttpGet("{id}")]
public async Task<IActionResult> GetItem(int id)
{
    var result = await _service.GetItem(id);
    return result.ToActionResult();
}

This maps ResultCode to appropriate HTTP responses like 200 OK, 404 NotFound, 400 BadRequest, etc., so you don't have to write repetitive logic.

πŸ”„ Coming Soon (Planned Features)

  • Result middleware for automatic API response wrapping
  • Built-in integration with FluentValidation
  • Localization support in Error

❀️ Contribute / Feedback

Feel free to open issues or pull requests for enhancements or bug reports.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Etymon.Result:

Package Downloads
Etymon.Result.Extensions

Etymon.Result.Extensions provides helper extensions for working with Etymon.Result, specifically for ASP.NET Core Web APIs.

GitHub repositories

This package is not used by any popular GitHub repositories.