You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CRUD操作校验逻辑层级选型:控制器还是仓储层?

CRUD操作前校验逻辑的层级选择最佳实践

1. 校验逻辑的分层原则

不同类型的校验,归属层级要区分开:

  • 请求合法性校验(比如参数格式、必填项检查):适合放在控制器(或者用模型验证、请求过滤器),毕竟控制器是HTTP请求的入口,先把明显无效的请求挡掉,避免后续层做无用功。
  • 业务规则校验(比如只有创建者能删除、已审批数据不能删这类业务相关的规则):不建议放在控制器或仓储层,最佳位置是业务逻辑层(Service层)。控制器的职责应该是接收请求、调用业务逻辑、返回响应,不该堆业务规则;仓储层只负责数据持久化操作,掺杂业务规则会让它职责混乱,也不利于复用。

2. 关于传递额外参数到仓储层的合理性

如果直接把校验逻辑丢去仓储层,还要传userId这类参数,这种做法不合理——仓储层要和业务规则、当前用户解耦,只专注于数据的增删改查。但如果是通过业务层来处理,业务层接收userId(从控制器传递过来)就完全合理,因为业务层本身就是封装业务规则的地方,需要这些参数来判断操作是否符合业务要求。

3. 重构示例参考

可以新增一个业务层类来封装删除逻辑和校验:

public class DailyReportService
{
    private readonly IUnitOfWork _unitOfWork;

    public DailyReportService(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public (bool Success, string Message) RemoveReport(int reportId, int currentUserId)
    {
        var report = _unitOfWork.DailyReportPipingRepository.Find(reportId);
        if (report == null)
            return (false, "Invalid Data");

        if (report.fldUserId != currentUserId)
            return (false, "Incorrect user");

        if (report.fldApproved || report.fldFinalized)
            return (false, "Approved or finalized before");

        try
        {
            _unitOfWork.DailyReportPipingRepository.Remove(report);
            var affectedRows = _unitOfWork.SaveChangesByUserId(currentUserId);
            if (affectedRows == 0)
                return (false, "unable to save");
            
            return (true, string.Empty);
        }
        catch (Exception ex)
        {
            return (false, ex.Message);
        }
    }
}

然后控制器就能简化成只做请求转发和响应:

public IActionResult OnPostRemove(int id)
{
    var currentUserId = HttpContext.Session.GetActiveUser_UserId();
    var result = _dailyReportService.RemoveReport(id, currentUserId);
    
    if (!result.Success)
        return new JsonResult(new { status = false, message = result.Message });
    
    return new JsonResult(true);
}

4. 总结

  • 控制器只做“中转站”,剥离业务逻辑后更简洁,符合单一职责原则。
  • 仓储层保持纯粹的数据操作,不掺和业务规则,避免职责边界模糊。
  • 业务层接收userId等业务参数是合理的,这是它处理业务规则的必要输入。

内容的提问来源于stack exchange,提问作者Hadi Mazareei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:18:36