OnRail 1.2.0
See the version list below for details.
dotnet add package OnRail --version 1.2.0
NuGet\Install-Package OnRail -Version 1.2.0
<PackageReference Include="OnRail" Version="1.2.0" />
paket add OnRail --version 1.2.0
#r "nuget: OnRail, 1.2.0"
// Install OnRail as a Cake Addin #addin nuget:?package=OnRail&version=1.2.0 // Install OnRail as a Cake Tool #tool nuget:?package=OnRail&version=1.2.0
OnRail library
Simple and powerful Railway Oriented library for C#.
Simple Sample
using FunctionalUtility.Extensions;
TryExtensions.Try(() => {
Console.Write("Enter a number: ");
var input = Console.ReadLine();
return Convert.ToInt32(input);
})
.OnSuccess(number => Console.WriteLine($"Number is valid: {number}"))
.OnFail(result => {
Console.WriteLine("Result:");
Console.WriteLine($"Is Success? {result.IsSuccess}"); //Is Success? False
Console.WriteLine($"Error title: {result.Detail.Title}"); //Sample: Error title: ExceptionError
Console.WriteLine($"Error message: {result.Detail.Message}"); //Sample: Error message: Input string was not in a correct format.
});
Document
The output of each method is a MethodResult class. The MethodResult class has two important fields.
- IsSuccess: Determines whether the operation was successful or not.
- Detail: It keeps more details of the result. Like title, message, etc.
There are two types of MethodResult:
MethodResult
: Simple MethodResult that have no data.MethodResult<T>
: MethodResult that holds data of type T.
The MethodResult class has two important methods.
Ok: Indicates that the operation was successful and can include data and detail.
MethodResult.Ok()
MethodResult<string>.Ok("Hello")
MethodResult.Ok(new ResultDetail(statusCode: 200, "Title", "Message"))
MethodResult<string>.Ok("Hello", new ResultDetail(statusCode: 200, "Title", "Message"))
Fail: Indicates that the operation failed and contains detail.
MethodResult.Fail(new BadRequestError("title", "message"))
Sample
using FunctionalUtility.ResultUtility;
// This method returns "Hello" string.
private static MethodResult<string> GetHello() {
return MethodResult<string>.Ok("Hello");
}
public static MethodResult PrintHello() =>
GetHello()
.OnSuccess(message => Console.WriteLine(message))
.OnFail(result => Console.WriteLine($"Operation failed. {result.Detail.Title}-{result.Detail.Message}"));
public static MethodResult PrintHelloVerbose() {
var messageResult = GetHello();
if (!messageResult.IsSuccess) {
//Operation was not successful. Print detail.
var detail = messageResult.Detail;
Console.WriteLine($"Operation failed. {detail.Title}-{detail.Message}");
return MethodResult.Fail(detail);
}
//Operation was successful.
Console.WriteLine(messageResult.Value); //Hello
return MethodResult.Ok();
}
Custom ResultDetail
For simplicity, you can customize the ResultDetail:
public class CustomDetail : ResultDetail {
public CustomDetail(int statusCode = 1000, string title = "Custom Title",
string? message = "Custom Message") : base(statusCode, title, message) { }
}
static void PrintCustomDetail() =>
MethodResult.Fail(new CustomDetail())
.OnFail(result => {
var detail = result.Detail;
Console.WriteLine(detail.StatusCode); //1000
Console.WriteLine(detail.Title); //Custom Title
Console.WriteLine(detail.Message); //Custom Message
});
You can also customize the fields:
public class CustomDetail : ResultDetail {
public string CustomField { get; set; }
public CustomDetail(string customField, int statusCode = 1000, string title = "Custom Title",
string? message = "Custom Message") : base(statusCode, title, message) {
CustomField = customField;
}
}
static void PrintCustomDetail() =>
MethodResult.Fail(new CustomDetail("Custom Field"))
.OnFail(result => {
if (result.Detail is CustomDetail customDetail) {
Console.WriteLine(customDetail.CustomField); //Custom Field
}
var detail = result.Detail;
Console.WriteLine(detail.StatusCode); //1000
Console.WriteLine(detail.Title); //Custom Title
Console.WriteLine(detail.Message); //Custom Message
});
Customize Error Details
It is better to inherit from the ErrorDetail class to customize the error details. Because the ErrorDetail class includes fields like StackTrace and exception data.
ResultDetail is a base class for successful and unsuccessful operations. But the ErrorDetail class is designed for failed operations.
Usually, to increase the security of the program, the details of the errors (such as 500 errors in the server) are not displayed to users. With the ShowDefaultMessageToUser field in the ErrorDetail class you can specify whether the default message is displayed or not.
For example:
static MethodResult Print(bool showDefaultMessage) =>
MethodResult.Fail(new InternalError(message: "This is an important bug",
showDefaultMessageToUser: showDefaultMessage))
.OnFail(result => Console.WriteLine(result.Detail.GetViewModel()));
Print(false);
/*
* Output:
* { StatusCode = 500, Title = InternalError, Message = This is an important bug }
*/
Print(true);
/*
* Output:
* { StatusCode = 500, Title = Error!, Message = something went wrong. }
*/
Add More Details
You can easily add the objects you need to the details.
static MethodResult Print(string input) =>
MethodResult.Fail(new BadRequestError())
.OnFail(result => result.Detail.AddDetail(new {input}))
.OnFail(result => {
if (result.Detail.MoreDetails is null)
return;
foreach (var detail in result.Detail.MoreDetails) {
Console.WriteLine(detail);
}
});
/*
* Sample Output:
* { input = Test }
*/
Default ResultDetail
Types of Result Details that exist:
- BadRequestError.cs
- ConflictError.cs
- ErrorDetail.cs
- ExceptionData.cs
- ExceptionError.cs
- ForbiddenError.cs
- InternalError.cs
- NotFoundError.cs
- NotImplementedError.cs
- UnauthorizedError.cs
Product | Versions 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. |
.NET Core | netcoreapp3.1 is compatible. |
-
.NETCoreApp 3.1
- Microsoft.AspNetCore.Mvc.Core (>= 2.2.5)
- Microsoft.Extensions.Configuration.Binder (>= 6.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.