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

ASP.NET中如何为自定义DataAnnotation注入依赖对象?

解决自定义DataAnnotation依赖注入的问题

在ASP.NET Core中,直接给自定义ValidationAttribute添加带依赖的构造函数确实行不通,因为属性注解要求无参构造。这里提供两种实用的解决思路:

方法一:在Validate方法中通过ValidationContext获取依赖

修改你的CheckForGenderAndBatchAttribute,不在构造函数中注入IBatchRepository,而是在Validate方法里通过ValidationContext的GetService方法获取所需服务:

public class CheckForGenderAndBatchAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // 从ValidationContext中获取IBatchRepository实例
        var batchRepo = validationContext.GetService(typeof(IBatchRepository)) as IBatchRepository;
        if (batchRepo == null)
        {
            return new ValidationResult("无法获取批次仓库服务");
        }

        // 获取当前Coach模型实例,拿到性别信息
        var coach = validationContext.ObjectInstance as Coach;
        if (coach == null)
        {
            return ValidationResult.Success;
        }

        int batchId = (int)value;
        var batch = batchRepo.GetById(batchId); // 假设仓库实现了该查询方法
        if (batch == null)
        {
            return new ValidationResult("指定批次不存在");
        }

        // 执行校验规则:男性教练不能分配至女性专属批次
        if (coach.Gender == Gender.Male && batch.IsFemaleOnly)
        {
            return new ValidationResult("男性教练无法分配至女性专属批次");
        }

        return ValidationResult.Success;
    }
}

之后直接在Coach模型的BatchId属性上标记该注解即可:

public class Coach
{
    public int Id { get; set; }
    public Gender Gender { get; set; }

    [CheckForGenderAndBatch]
    public int BatchId { get; set; }
    public Batch Batch { get; set; }
}

关键前提:确保IBatchRepository及其实现类已注册到DI容器,比如在Program.cs中添加:

builder.Services.AddScoped<IBatchRepository, BatchProjectDbRepository>();

方法二:改用IValidatableObject接口

如果不想自定义Attribute,也可以让Coach模型实现IValidatableObject接口,直接在模型内编写校验逻辑,同样通过ValidationContext获取依赖:

public class Coach : IValidatableObject
{
    public int Id { get; set; }
    public Gender Gender { get; set; }
    public int BatchId { get; set; }
    public Batch Batch { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var batchRepo = validationContext.GetService(typeof(IBatchRepository)) as IBatchRepository;
        if (batchRepo == null)
        {
            yield return new ValidationResult("无法获取批次仓库服务");
            yield break;
        }

        var batch = batchRepo.GetById(BatchId);
        if (batch == null)
        {
            yield return new ValidationResult("指定批次不存在", new[] { nameof(BatchId) });
            yield break;
        }

        if (Gender == Gender.Male && batch.IsFemaleOnly)
        {
            yield return new ValidationResult("男性教练无法分配至女性专属批次", new[] { nameof(BatchId) });
        }
    }
}

这种方式更灵活,无需额外定义Attribute,适合校验逻辑与模型绑定较紧密的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:46:12