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

Blazor WASM自定义唯一约束ValidationAttribute实现方案咨询

可行解决方案如下

方案1:远程校验组合标记属性(推荐,逻辑统一无冲突)

该方案完全规避Shared项目访问Server的限制,同时保证前后端校验逻辑一致:

  • 在Shared项目中仅定义标记用的UniqueAttribute,不包含任何校验逻辑,仅存储唯一校验关联的实体元数据:
[AttributeUsage(AttributeTargets.Property)]
public class UniqueAttribute : Attribute
{
    /// <summary>
    /// 对应校验的实体类型
    /// </summary>
    public Type EntityType { get; }
    public UniqueAttribute(Type entityType)
    {
        EntityType = entityType;
    }
}
  • 给Shared项目中的实体属性添加上述标记,示例:
public class ApplicationUser
{
    public int Id { get; set; }
    [Unique(typeof(ApplicationUser))]
    public string UserAccount { get; set; }
}
  • Server端新增通用唯一校验接口,接收参数为:实体类型名、校验属性名、属性值、当前编辑实体ID(编辑场景用于排除自身),查询DBContext返回是否存在重复值即可。
  • Client项目中实现客户端侧的自定义校验属性,继承ValidationAttribute,内部调用你封装的HttpService请求上述校验接口,获取结果返回校验状态。Blazor的EditForm原生支持异步校验逻辑,结果返回后会自动标记对应Input控件的错误状态:
public class ClientUniqueValidationAttribute : ValidationAttribute
{
    protected override async Task<ValidationResult> IsValidAsync(object value, ValidationContext validationContext)
    {
        var httpService = validationContext.GetRequiredService<IHttpService>();
        var uniqueAttr = validationContext.ObjectType
            .GetProperty(validationContext.MemberName)
            .GetCustomAttribute<UniqueAttribute>();
        
        // 调用后端校验接口
        var isDuplicate = await httpService.PostAsync<bool>("/api/validation/check-unique", new 
        {
            EntityName = uniqueAttr.EntityType.Name,
            PropertyName = validationContext.MemberName,
            InputValue = value?.ToString(),
            CurrentId = (validationContext.ObjectInstance as IEntityBase)?.Id
        });

        return isDuplicate 
            ? new ValidationResult($"{validationContext.DisplayName}已存在,请更换") 
            : ValidationResult.Success;
    }
}

注意:前端校验仅为提升用户体验的前置逻辑,你已实现的后端唯一约束必须保留,防止恶意请求绕过前端校验直接调用接口。

方案2:前端预缓存校验(仅适合小数据量场景)

如果需要校验的实体数据量极小(如少于100条的字典类数据),可以在页面初始化时一次性拉取所有已存在的属性值到前端缓存,自定义校验属性直接在前端匹配缓存判断是否重复。该方案不需要实时请求接口,但实时性差,数据量大时会浪费带宽,不推荐通用场景使用。

方案3:封装通用校验组件

可以针对需要唯一校验的输入场景封装单独的InputUniqueText组件,将远程校验逻辑内置在组件内部,复用性更高,不需要每个表单单独配置校验规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:48:02