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

基于C# N层架构的文件共享系统输入验证方案咨询

在N层架构的业务逻辑层实现带详细错误的输入验证

我懂你现在的痛点——原本的NewFile方法只返回个布尔值,用户根本不知道到底哪错了,是文件名空了?还是格式不对?完全摸不着头脑对吧?要实现带具体错误提示的验证,咱们得把返回值从bool改成能承载错误信息的对象,再在业务逻辑层里加验证逻辑,一步步来:

1. 先定义验证结果和错误信息的模型

首先得有个类来封装验证是否成功,以及具体的错误细节:

public class ValidationResult
{
    public bool IsSuccess { get; set; }
    public List<ValidationError> Errors { get; set; } = new List<ValidationError>();
}

public class ValidationError
{
    public string FieldName { get; set; } // 出错的字段,比如"FileName"
    public string ErrorType { get; set; } // 错误类型,比如"Required"、"InvalidFormat"
    public string Message { get; set; } // 给用户看的友好提示
}

如果想更规范,ErrorType可以用枚举代替字符串,避免拼写错误:

public enum ErrorType
{
    Required,
    InvalidFormat,
    InvalidValue,
    SystemError
}

2. 修改业务逻辑层的NewFile方法

接下来把原来只返回bool的方法改成返回上面的ValidationResult,并在调用仓储层之前加入验证逻辑。这里假设你的File类还有FileName这类常见字段,我补全了常见的验证场景:

public class FileBusinessLogic
{
    private readonly IFileRepository _repo;

    // 依赖注入仓储层,符合N层架构的解耦原则
    public FileBusinessLogic(IFileRepository repo)
    {
        _repo = repo;
    }

    public ValidationResult NewFile(File entity)
    {
        var result = new ValidationResult();

        // 验证必填字段:文件名不能为空
        if (string.IsNullOrWhiteSpace(entity.FileName))
        {
            result.Errors.Add(new ValidationError
            {
                FieldName = nameof(entity.FileName),
                ErrorType = ErrorType.Required.ToString(),
                Message = "文件名不能为空或仅包含空白字符"
            });
        }

        // 验证文件格式:只允许指定后缀
        if (!string.IsNullOrWhiteSpace(entity.FileName))
        {
            var allowedExtensions = new[] { ".pdf", ".doc", ".docx", ".jpg", ".png" };
            var fileExtension = Path.GetExtension(entity.FileName).ToLower();
            if (!allowedExtensions.Contains(fileExtension))
            {
                result.Errors.Add(new ValidationError
                {
                    FieldName = nameof(entity.FileName),
                    ErrorType = ErrorType.InvalidFormat.ToString(),
                    Message = $"仅支持以下文件格式:{string.Join(", ", allowedExtensions)}"
                });
            }
        }

        // 验证UploadId:必须是正整数
        if (entity.UploadId <= 0)
        {
            result.Errors.Add(new ValidationError
            {
                FieldName = nameof(entity.UploadId),
                ErrorType = ErrorType.InvalidValue.ToString(),
                Message = "上传ID必须是有效的正整数"
            });
        }

        // 验证通过后,再调用仓储层插入数据
        if (!result.Errors.Any())
        {
            bool insertSuccess = _repo.Insert(entity);
            result.IsSuccess = insertSuccess;
            
            // 如果仓储层插入失败,添加系统错误提示
            if (!insertSuccess)
            {
                result.Errors.Add(new ValidationError
                {
                    FieldName = "System",
                    ErrorType = ErrorType.SystemError.ToString(),
                    Message = "文件信息保存失败,请稍后重试"
                });
            }
        }

        return result;
    }
}

3. 在调用层(UI/API)处理验证结果

现在调用NewFile之后,就能拿到详细的错误信息,直接展示给用户了:

// 示例:在API控制器或者UI逻辑里调用
var fileBll = new FileBusinessLogic(new FileRepository());
var newFile = new File
{
    UploadId = 0,
    FileName = "notes.txt"
};

var validationResult = fileBll.NewFile(newFile);
if (!validationResult.IsSuccess)
{
    // 遍历错误信息,展示给用户
    foreach (var error in validationResult.Errors)
    {
        Console.WriteLine($"【{error.FieldName}】{error.Message}");
        // 如果是API的话,可以返回400 Bad Request,把错误列表序列化给前端
    }
}
else
{
    Console.WriteLine("文件信息已成功保存");
}

额外优化建议

  • 如果项目规模较大,可以用FluentValidation这类成熟的验证库,能减少重复的验证代码,写法更简洁
  • 可以把验证逻辑抽成单独的方法(比如ValidateFileEntity(File entity)),让NewFile方法更专注于业务流程
  • 错误提示可以做成多语言的,适配不同地区的用户

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:28:35