.NET 结果与错误处理利器 FluentResults
前言
在项目开发中,方法返回的结果(成功或失败)对我们开发来说很重要。传统方法,如通过异常来指示错误或使用特定的返回类型(如布尔值加输出参数),虽然有效,但可能缺乏直观性和灵活性。
FluentResults库应运而生,它以一种既流畅又富有表达力的方式,极大地优化了这一过程。通过使用FluentResults,能够以一种更加自然和易于理解的方式传递操作结果,包括成功状态、错误信息、警告以及额外信息,提高代码的可读性和可维护性。
这种方式不仅让错误处理更加集中和一致,还使得代码结构更加清晰,逻辑更加流畅。
项目介绍
FluentResults 是一个在 .NET 环境中广泛使用的库,它提供了一种优雅的方式来处理方法执行的结果和错误。
使用 FluentResults,可以很容易地创建包含成功值、错误、警告或信息的对象,并通过链式调用来处理这些对象。
那么如何使用 FluentResults 来优雅地处理结果和错误信息呢?
使用 FluentResults
1、安装 FluentResults
首先,在项目中安装 FluentResults,可以通过 NuGet 包管理器来安装。在 Visual Studio 中也可以通过 NuGet 包管理器控制台输入以下命令:
Install-Package FluentResults
或者,在项目文件中添加 NuGet 包引用。

2、创建 Result 对象
使用 Result 类的静态方法来创建结果对象。Result 类提供了多种方法来创建不同类型的结果,例如成功、失败、带有警告或信息的成功等。
using FluentResults;
static void Main(string[] args)
{
var result = IsInteger("");
if (result.IsSuccess)
{
Console.WriteLine($"结果:{result.Value} ");
}
else
{
Console.WriteLine($"结果:{result.Reasons[0].Message}|{result.Errors[0].Message}");
}
}
public static Result<int> IsInteger(string input)
{
// 假设输入为空或null,我们可以选择认为它不是数字
if (string.IsNullOrWhiteSpace(input))
{
return Result.Fail<int>("输入为空或null,无法判断是否是数字");
}
// 使用int.TryParse尝试将输入转换为整数
// 如果转换成功,out参数将包含转换后的值,方法返回true
// 如果转换失败,方法返回false
if (int.TryParse(input, out int result))
{
return Result.Ok(result);
}
// 如果无法转换为整数,则认为输入不是数字
return Result.Fail<int>("输入不是数字");
}
运行结果

通过使用Result 类我们可以看到,方法运行返回了标准的接口参数,包括IsSuccess,Message,Errors等参数,帮我们快速实现返回结构。
3、链式处理结果
FluentResults 允许你通过链式调用来处理结果,这使得错误处理和逻辑流程更加清晰和直观。
需要注意的是FluentResults 本身的 Result 类型并不直接提供 OnSuccess 和 OnFailure 这样的链式方法,因为这些方法可能是在 FluentResults 的某个版本中以扩展方法的形式添加的,或者是在基于 FluentResults 的自定义扩展中定义的。
自定义扩展类
/// <summary>
/// Result 扩展方法
/// </summary>
public static class ResultExtensions
{
/// <summary>
/// 成功回调
/// </summary>
/// <param name="result"></param>
/// <param name="successAction"></param>
/// <returns></returns>
public static Result OnSuccess(this Result result, Action successAction)
{
if (result.IsSuccess)
{
successAction?.Invoke();
}
return result; // 返回结果以支持链式调用
}
/// <summary>
/// 失败回调
/// </summary>
/// <param name="result"></param>
/// <param name="failureAction"></param>
/// <returns></returns>
public static Result OnFailure(this Result result, Action<IError> failureAction)
{
if (!result.IsSuccess && result.Errors!= null)
{
foreach (var error in result.Errors)
{
failureAction?.Invoke(error);
}
}
return result; // 返回结果以支持链式调用
}
}
自定义方法
/// <summary>
/// 验证输入字符串是否为整数
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static Result IsIntegerInfo(string input)
{
// 假设输入为空或null,我们可以选择认为它不是数字
if (string.IsNullOrWhiteSpace(input))
{
return Result.Fail("输入为空或null,无法判断是否是数字");
}
// 使用int.TryParse尝试将输入转换为整数
// 如果转换成功,out参数将包含转换后的值,方法返回true
// 如果转换失败,方法返回false
if (int.TryParse(input, out int result))
{
return Result.Ok();
}
// 如果无法转换为整数,则认为输入不是数字
return Result.Fail("输入不是数字");
}
调用示例
var result = IsIntegerInfo("")
.OnSuccess(() =>
{
// 处理成功的情况
Console.WriteLine("Success!");
})
.OnFailure(error =>
{
// 处理失败的情况
Console.WriteLine("Failed: " + error.Message);
});
// 注意:在 OnSuccess 或 OnFailure 中使用 result 变量可能不是安全的,
// 因为这些回调可能在这些回调执行之前就被修改了。
// 更好的做法是在 OnSuccess/OnFailure 的 lambda 表达式中使用局部变量。
运行结果

在这个示例中定义了两个扩展方法 OnSuccess 和 OnFailure,它们分别接受成功和失败时要执行的回调函数。这些方法首先检查 Result 对象的状态,然后根据状态调用相应的回调函数。最后,它们返回原始的 Result 对象,以支持链式调用。
请注意,示例是为了说明目的而简化的,并且可能不包含 FluentResults 库中实际可用的所有功能和优化。在实际应用中,应该查看 FluentResults 的文档和源代码,以了解提供的具体功能。
4、FluentResults 高级特性
FluentResults提供许多高级特性,如链式调用、自定义错误类型、以及包含额外数据和元数据的错误对象。
例如,可以使用Result.Fail的重载版本来包含更多的上下文信息
return Result.Fail("输入错误.").WithError("The input value must be greater than zero.");
5、自定义 Result 类型
FluentResults 还支持通过继承 Result 类来创建自定义的结果类型,以便在结果中携带额外的数据或状态。
public class CommonResult
{
public Result Result { get; }
public string MyData { get; }
public CommonResult(Result result, string myData)
{
Result = result;
MyData = myData;
Console.WriteLine($"{nameof(CommonResult)}: {MyData}|{result}");
}
}
调用示例
public static CommonResult DemoResult(string input)
{
bool isSuccess =false;
string errorMessage = "输入的字符串不是数字";
string myData = "测试一下";
Result result = isSuccess ? Result.Ok() : Result.Fail(errorMessage);
return new CommonResult(result, myData);
}
运行结果

通过以上步骤,可以在 .NET 应用快速、方便的使用 FluentResults 来处理结果和错误。可以提高代码的可读性和可维护性,还可以使错误处理更加集中和统一规范。
使用场景
- API 开发:在处理 HTTP 请求和响应时,FluentResults 构建清晰、一致和易于理解的错误响应。
- 业务逻辑验证:在执行业务逻辑验证时,FluentResults 可以验证多个错误,并一次性返回。
- 复杂操作的结果处理:当需要处理包含多个步骤的复杂操作时,FluentResults 可以帮助管理每个步骤的结果,并将它们组合成一个最终的结果。
总结
FluentResults 提供了丰富的 API,可以灵活使用,与现有的 .NET 代码库和框架集成,如 ASP.NET Core、Entity Framework 等,还可以与其他第三方库一起使用,以提供更全面的错误处理和结果功能。
如果你的项目中需要一种更好的方式来处理结果,并希望提高代码的可读性和可维护性,那么 FluentResults 是一个不错的选择。
开源地址
https://github.com/altmann/FluentResults
如果觉得这篇文章对你有用,欢迎加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行交流心得,共同成长。

.NET 结果与错误处理利器 FluentResults的更多相关文章
- dos命令
一 .常用命令 1 dir无参数:查看当前所在目录的文件和文件夹./s:查看当前目录已经其所有子目录的文件和文件夹./a:查看包括隐含文件的所有文件./ah:只显示出隐含文件./w:以紧凑方式(一行显 ...
- dos笔记
MS DOS 命令大全 一.基础命令 1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出隐含 ...
- DOS 命令大全
MS DOS 命令大全 一.基础命令 1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出隐含 ...
- 常用的dos命令之简略总结
Dos常用命令 一.基础命令 1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出 ...
- Windows常用的一些DOS命令整理
Windows常用的一些DOS命令整理.. MS DOS 命令大全 ---清空Dos屏幕使用命令:cls -- Dos切换当前目录到D盘:cd d: 一.基础命令 1 dir 无参数:查看当前所在目录 ...
- 常用Dos操作指令
1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出隐含文件. /w:以紧凑方式(一行显示5个 ...
- Dos常用命令大全
dos命令进入文件夹 输入 D: 回车,进入D盘的根目录,然后输入dir 回车 可以查看根目录下的文件和文件夹, 输入 cd空格文件夹的名字(不区分大小写) 进入文件夹根目录下, 依次输入dir 查 ...
- Dos命令大全(1)
MS DOS 命令大全 一.基础命令 1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出隐含 ...
- 航空概论(历年资料,引之百度文库,PS:未调格式,有点乱)
航空航天尔雅 选择题1. 已经实现了<天方夜谭>中的飞毯设想.—— A——美国2. 地球到月球大约—— C 38 万公里3. 建立了航空史上第一条定期空中路线—— B——德国4. 对于孔明 ...
- MS DOS 常用命令整理
最近在开发用到一些dos下的一些指令,还有bat文件,特别是bat的便捷性让我在生活和开发过程中好好使用. dos指令: java com.pdcss.util.JacobService > D ...
随机推荐
- MySQL学习笔记-多表查询(上)
多表查询(上) 一. 多表关系 在实际应用中,根据需求,设计的表结构之间存在联系,联系一般分为以下三种 一对多(多对一) 多对多 一对一 1. 一对多(多对一) 案例:部门与员工的关系,一个部门对应多 ...
- wordpress 折腾记
今天我看到一篇个人博客,我想建个人网站的心又动了. 虽说博客园已经很符合我的预期了,但我还是一直很想做一个个人网站做一些个性化的东西,今天试试用用wordpress搭建一个wordpress网站 介绍 ...
- knife4j/swagger救援第一现场
1.前方来报,测试环境springboot项目无法启动,现场如下: Error starting ApplicationContext. To display the auto-configurati ...
- Easysearch 压缩功能的显著提升:从 8.7GB 到 1.4GB
引言 在海量数据的存储和处理中,索引膨胀率是一个不可忽视的关键指标.它直接影响了存储成本和查询性能.近期,Easysearch 在这方面取得了显著的进展,其压缩功能的效果远超过了之前的版本.本文将详细 ...
- 限速上传文件到腾讯对象存储cos的脚本
官网:https://cloud.tencent.com/document/product/436/12269 安装包,这里用的python2.7 # pip install -U cos-pytho ...
- 贝壳找房: 为 AI 平台打造混合多云的存储加速底座
贝壳机器学习平台的计算资源,尤其是 GPU,主要依赖公有云服务,并分布在不同的地理区域.为了让存储可以灵活地跟随计算资源,存储系统需具备高度的灵活性,支持跨区域的数据访问和迁移,同时确保计算任务的连续 ...
- Docker入门系列之三:十二个Dockerfile指令
本篇文章是关于Dockerfiles的,这是Docker系列文章的第三部分.如果您还没有读过第一部分,请先阅读它,您可以从全新的角度了解Docker容器概念. 第二部分是Docker生态系统的简要介绍 ...
- cv2 判断图片是冷还是暖
把图片的颜色空间转为HSV H表示色调(下图横轴), 图片的平均H值可用于区分冷暖
- Ubuntu下nvidia驱动卸载
Ubuntu下nvidia驱动卸载的一种方法 卸掉已经安装的驱动: sudo apt-getremove --purge '^nvidia-.*' sudo apt-getremove --purge ...
- Stable Diffusion(二)WebUI使用指南
1. 前言 基于 https://stable-diffusion-art.com/ 内的教程进行翻译与整理,帮助快速上手 stable-diffusion 的使用. 2. 环境 AWS DeepLe ...