Elephant.Types.Results 1.1.0

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

Nuget downloads NuGet Downloads Workflow License: MIT

About

Continuation of my older ResponseWrappers from the Elephant.Types Nuget downloads. I renamed it to Result because its much shorter and made a variety of improvements.

Why use the result pattern

There are really many reasons that can be found online. I'll highlight the 3 that I personally find the most important:

  1. Better performance. than exceptions.
  2. I don't like throwing exceptions for something that is expected.
  3. In some situations (e.x. n-tier) you don't want to be dealing with HTTP status codes in your data access- and business logic layers.

Installation

Choose one:

Package Manager (Visual Studio GUI)

  1. Right-click your project → "Manage NuGet Packages".
  2. Search for Elephant.Types.Results.
  3. Click "Install".

.NET CLI (Command Line)

dotnet add package Elephant.Types.Results

PackageReference (Project File)

<PackageReference Include="Elephant.Types.Results" Version="x.x.x" />

Package Manager (CLI)

nuget install Elephant.Types.Results

How to Use

Usage examples

With data

public async Task<IResult<Customer>> UpdateCustomerAsync(Customer customer, CancellationToken cancellationToken)
{
	// Update customer logic here.

    return Result<Customer>.Ok(updatedCustomer, "Optional message here.");
}

Without data

public async Task<IResult> UpdateCustomerAsync(Customer customer, CancellationToken cancellationToken)
{
    Customer? customerInDb = _customerRepository.ById(customer.Id);
    if (customerInDb == null)
		return Result.NotFoundNoData();
    
    // Update customer logic here.
}

public async Task<IResult> UpdateCustomerAsync(Customer customer, CancellationToken cancellationToken)
{
    Customer? customerInDb = await _customerRepository.ByIdAsync(customer.Id);
    if (customerInDb == null)
		Result.NotFoundNoData($"{nameof(Customer)} with {nameof(Customer.Id)} {Customer.Id} not found.");
    
	// Update customer logic here.

	return Result.OkNoData();
}

Multi status support

private IResult<string> ErrorMethod(bool errorOccurred)
{
	IResult<string> result = Result<string>.Ok("Success.");

	if (errorOccurred)
    {
        // You can chain different statuses as long as the generic is of the same type.
        // That means you can't combine the data and the no-data versions in the same chain because
        // they have a different return type.
		result.AddError("Error 1")
			.AddInternalServerError("Error 2")
			.AddContinue("Continue")
			.AddOk("Ok data")
			.AddConflict("Concurrency conflict on ..");
    }

	return result;
}

private IResult ChainNoDataMethod()
{
	IResult result = Result.OkNoData();
	result.AddErrorNoData("Unable to fetch cat food.")
		.AddInternalServerErrorNoData("Unable to fetch cat food.")
		.AddInternalServerErrorNoData()
		.AddInternalServerErrorNoData("Unable to fetch cat food.")
		.AddContinueNoData("Continue")
		.AddConflictNoData("Concurrency conflict on ..");

	return result;
}

Custom errors

return Result.ErrorNoData("Something went wrong.");
return Result<Customer>.Error(new YourCustomException(), 23122, customer); // With 23122 being your optional custom code.

Unwrap in controller

If you easily want to unwrap it in your controller, you may use the NuGet Elephant.ApiController version 3.0.0 or greater and then:

// Your attributes here.
MyController : ElephantControllerBase
{
	[HttpPost]
	[Route("customer-create-test")]
	[ProducesResponseType(typeof(List<Customer>), StatusCodes.Status201Created)]
	[ProducesResponseType(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> CreateCustomers(List<CustomerCreateRequestModel> requestModel, CancellationToken cancellationToken)
	{
        IResult<Customer> result = await _customerService.Create(requestModel, cancellationToken);

        // Will return a 201 created response along with the created customers (assuming that your service returns them).
        return Unwrap(result);
	}
    
	[HttpPost]
	[Route("order-create-test")]
	[ProducesResponseType(StatusCodes.Status201Created)]
	[ProducesResponseType(StatusCodes.Status400BadRequest)]
	public async Task<IActionResult> CreateOrders(List<OrderCreateRequestModel> requestModel, CancellationToken cancellationToken)
	{
        IResult result = await _orderService.Create(requestModel, cancellationToken);

        // Will return a 201 created response without any order data.
        return Unwrap(result);
	}
}

Other

You can override Result.GetResultStatus if for example you want to prioritize different statuses using custom logic.

You can create custom statuses as long as you derive from IResultStatus.

You can also override the success, error, informative and custom status checks in the ResultStatus class. This way you can create custom errors and successes and etc.

Contributing

Contributions are welcome. Please read our CONTRIBUTING.md file for guidelines on how to proceed.

License

This project is licensed under the MIT License. See the LICENSE.txt file for details.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Elephant.Types.Results:

Package Downloads
Elephant.Database

Common EF Core database code.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 287 12/31/2025
1.0.3 709 11/4/2023

Bugfix: Result.InternalServerError should use its parameter.