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

构造函数抛出异常:WebAPI中PessoaModel类参数校验实现问询

正确实现PessoaModel构造函数的参数校验与异常抛出

看起来你想通过构造函数校验来保证PessoaModel的实例始终是有效的,这个思路非常棒——毕竟对象创建时就确保合法性,比后续到处做校验靠谱多了。不过你当前的无参构造函数写法有个问题:当你实例化new PessoaModel()时,所有属性都是默认值(比如PessoaNome是null),这时候校验会直接抛出异常,而且调用者根本没机会给属性赋值。

咱们来调整一下,用带参数的构造函数来实现正确的校验逻辑,同时让代码更健壮:

public class PessoaModel 
{
    public int PessoaId { get; set; }
    public string PessoaNome { get; set; }
    public string PessoaNomeFantasia { get; set; }
    public string PessoaCnpjCpf { get; set; }
    public string PessoaEmail { get; set; }

    // 带必填参数的构造函数,强制调用者传入核心字段
    public PessoaModel(string pessoaNome, string pessoaEmail)
    {
        // 校验Nome:不能为空、空字符串或全空格
        if (string.IsNullOrWhiteSpace(pessoaNome))
            throw new ArgumentException("Nome da pessoa não pode ser vazio ou nulo.", nameof(pessoaNome));
        
        // 校验Email:先判断非空,再校验格式
        if (string.IsNullOrWhiteSpace(pessoaEmail))
            throw new ArgumentException("Email da pessoa não pode ser vazio ou nulo.", nameof(pessoaEmail));
        
        if (!IsValidEmailFormat(pessoaEmail))
            throw new ArgumentException("Formato de email inválido.", nameof(pessoaEmail));

        // 赋值给类属性
        PessoaNome = pessoaNome;
        PessoaEmail = pessoaEmail;
    }

    // 可选:保留无参构造函数(用于ORM框架如EF Core),但设为protected防止外部直接调用
    protected PessoaModel() { }

    // 辅助方法:校验Email格式(用MailAddress比正则更可靠)
    private bool IsValidEmailFormat(string email)
    {
        try
        {
            var mailAddress = new System.Net.Mail.MailAddress(email);
            return mailAddress.Address == email;
        }
        catch
        {
            return false;
        }
    }
}

关键细节说明:

  • 用带参数的构造函数替代无参构造:强制调用者在创建对象时就传入必填字段,从根源上避免创建无效实例。如果调用者不传参数,编译器会直接报错,比运行时抛异常更友好。
  • 使用针对性的异常类型:用ArgumentException代替通用的Exception,语义更清晰,调用者可以精准捕获参数错误的场景。
  • 精准的校验逻辑:用string.IsNullOrWhiteSpace代替单纯的== null,覆盖空字符串、全空格的无效场景。
  • 明确的异常信息:用nameof(pessoaNome)传递参数名,让调用者一眼就知道哪个参数出了问题,便于调试。
  • ORM兼容处理:如果需要和EF Core这类ORM框架配合,可以保留无参构造函数,但设置为protected,防止外部代码直接调用它创建无效对象。

额外优化建议:

  • 如果需要校验PessoaCnpjCpf的格式,可以添加类似IsValidCnpjCpf的辅助方法,在构造函数或属性的setter中校验。
  • 若校验规则复杂,推荐使用FluentValidation这类验证框架,把校验逻辑和实体类分离,代码更易维护。不过构造函数校验是保障对象一致性最直接的方式,两者可以结合使用。
  • 对于可选字段(如PessoaNomeFantasia),如果有格式要求,可以在属性的setter中添加校验,确保每次赋值都符合规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:48:52