c# - 验证方法和返回值 - 异常 vs 模型状态 vs Bool
问题描述
我的应用程序中有需要数据验证的规则,我通常会以三种不同的方式进行验证,我不确定我应该如何验证并将信息返回给控制器以显示给用户。
我正在将房屋对象添加到街道对象。有3条规则要遵守。
规则 1. 门牌号必须在 0-10 之间
方法:使用模型状态进行数据注释/验证
我通常会在模型中使用简单的数据注释来验证此规则
[Range(0,10, ErrorMessage = "Blah blah blah")]
然后在控制器中执行 ModelState.IsValid 检查。
规则 2. 门牌号和街道名称组合必须是唯一的
方法:Fluent API / 将抛出 SqlException
我通常会使用 Fluent API 实现此规则,如下所示
builder.Entity<Street>(b =>
{
b.HasIndex(e => new { e.HouseNumber, e.StreetName }).IsUnique();
});
当我尝试将其添加到数据库时,我希望这会引发异常,我将在服务层中捕获该异常。
规则 3 - 街道不能包含超过 10 间房屋
方法:服务层检查,并抛出异常或返回false
我通常会让我的控制器调用一个服务层,它会在调用存储库来保存数据之前检查业务规则。如果它不符合规则,它要么抛出异常。
throw new CreateHouseException("Street has reached maximum capacity");
或者干脆让方法返回false。
剩下的
如果需要,我的视图/视图模型都设置为返回状态消息,其中包含用户信息。
所有这些似乎与在三个位置以三种方式发生的业务规则验证非常脱节。
- 控制器检查模型状态
- 服务层检查手动编码的规则
- 违反 fluent API 设置时数据库抛出 SqlException
我觉得我应该将我的验证整合到一个位置,我确信这应该在服务层中完成。我做了一些研究,正在权衡以下几点
- 有人说我不应该将模型状态传递给服务层,因为这不利于关注点分离,并且无助于 Fluent API 验证引发的异常。
- 为从服务层到控制器的所有内容抛出太多异常似乎很容易解决,但很麻烦
- 流畅的 API 验证会引发异常,因此我必须以某种方式处理和组合模型状态和这些异常。
我知道其中一些可能是个人喜好。但是您将如何整合这 3 个方法,以及如何将必要的信息返回给控制器以传递给视图?
解决方案
推荐阅读
- mfc - MFC SDI OpenDocument() 正在重置我的主窗口大小。我怎样才能阻止它?
- python - 如何不在列表中包含打破循环的值
- kotlin - 我可以将 MutableStateFlow 对象直接传递给 StateFlow 变量吗?
- sql - SQL 根据表返回 count 有次要记录或零记录的记录
- javascript - Google Firebase RealtimeDB 规则不适用于 UID
- c - 将 void 指针转换为“类型”变量或使用 memcpy?
- swift - 如何在 Swift 中发送网络广播消息?
- java - 我想让两个克隆的范围不产生相同的结果
- sql - 即使数据库中不存在记录,如何检索默认值
- solana - 在 Ubuntu 上安装 solana - 它安装在哪里?