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

如何在Blazor自定义验证属性类中使用依赖注入的服务?

在Blazor Hybrid中实现依赖注入的自定义验证属性

在Blazor Hybrid场景下,ValidationAttribute的实例是在属性标记时创建的,无法直接通过构造函数注入Scoped服务。解决这个问题的核心思路是利用验证时传入的ValidationContext获取服务提供者,从而拿到你需要的BusinessConstantsLookup实例。

解决方案:通过ValidationContext获取服务

直接在IsValid方法中从ValidationContext提取服务,这样既能符合Scoped服务的生命周期,又能获取到依赖的ILookupService实例。

1. 实现CustomRangeAttribute

public class CustomRangeAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // 从ValidationContext中获取BusinessConstantsLookup实例
        var constantsLookup = validationContext.GetService(typeof(BusinessConstantsLookup)) as BusinessConstantsLookup;
        if (constantsLookup == null)
        {
            return new ValidationResult("无法获取业务常量查询服务");
        }

        // 从数据库获取验证所需的常量值(示例方法,根据你的实际逻辑调整)
        var allowedMin = constantsLookup.GetMinimumValidValue();
        var allowedMax = constantsLookup.GetMaximumValidValue();

        // 执行范围验证逻辑
        if (value == null)
        {
            return ValidationResult.Success; // 根据业务需求决定是否允许null值
        }

        if (value is int inputValue)
        {
            if (inputValue < allowedMin || inputValue > allowedMax)
            {
                return new ValidationResult($"输入值必须在{allowedMin}到{allowedMax}之间");
            }
        }
        else
        {
            return new ValidationResult("输入值类型无效");
        }

        return ValidationResult.Success;
    }
}

2. 在模型中使用自定义验证属性

public class YourFormModel
{
    [CustomRange]
    public int TargetProperty { get; set; }
}

3. Blazor组件中正常使用表单验证

<EditForm Model="@formModel" OnValidSubmit="@HandleSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <InputNumber @bind-Value="@formModel.TargetProperty" />
    <ValidationMessage For="@(() => formModel.TargetProperty)" />

    <button type="submit">提交</button>
</EditForm>

@code {
    private YourFormModel formModel = new YourFormModel();

    private void HandleSubmit()
    {
        // 处理表单提交逻辑
    }
}

关键注意事项

  • 禁止在ValidationAttribute的构造函数中获取Scoped服务:ValidationAttribute会被框架缓存为单例,直接在构造函数中注入Scoped服务会导致生命周期冲突(单例持有Scoped实例,无法正确释放)。
  • 确保服务注册正确:确认ILookupService和BusinessConstantsLookup已经在Main中完成Scoped注册:
    builder.Services.AddScoped<ILookupService, LookupService>();
    builder.Services.AddScoped<BusinessConstantsLookup>();
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:47:44