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

.NET 8 Blazor SSR模式下如何创建有效的自定义验证属性

.NET 8 Blazor SSR模式下如何创建有效的自定义验证属性

兄弟,我太懂你这种憋屈了——同样的自定义验证,在交互式服务器模式下顺顺当当,一切到SSR就只管拦着提交,错误消息却死活不露面,这简直让人摸不着头脑。我来给你拆解问题,再给你个能直接用的解决方案。

首先,你的自定义验证属性写法有个小疏漏,这也是SSR下不显示错误的核心原因:你在构造函数里直接初始化_defaultErrorMessage的方式,没跟上Blazor SSR验证系统的节奏。正确的姿势是重写FormatErrorMessage方法,而不是自己存一个错误字符串变量。

给你改好的验证属性代码,直接拿去用:

public class MinimumLengthAttribute : ValidationAttribute
{
    private readonly int _minLength;

    public MinimumLengthAttribute(int minLength)
    {
        _minLength = minLength;
    }

    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        // 先做验证逻辑
        if (value is string stringValue && stringValue.Length >= _minLength)
        {
            return ValidationResult.Success;
        }

        // 这里用FormatErrorMessage生成消息,而不是自己拼接
        return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    }

    // 重点:重写这个方法,适配SSR的验证消息处理机制
    public override string FormatErrorMessage(string name)
    {
        // 优先用用户自定义的ErrorMessage,没有就用默认模板
        return string.IsNullOrEmpty(ErrorMessage) 
            ? $"「{name}」的最小长度为{_minLength}位" 
            : string.Format(ErrorMessageString, name, _minLength);
    }
}

为啥要这么改?因为Blazor SSR的验证系统依赖FormatErrorMessage来正确解析错误消息,包括处理占位符、资源文件这些。你原来的写法跳过了这个机制,导致SSR下错误消息没法被ValidationMessage组件识别到。

接下来,再确认你的EditForm配置有没有踩坑,这几点在SSR下缺一不可:

  • 必须在EditForm里面加<DataAnnotationsValidator />,这是Blazor验证的“开关”,不管什么模式都不能丢;
  • 每个输入组件后面必须对应加<ValidationMessage For="@(() => 你的模型.属性名)" />,这是显示单属性错误的容器,SSR下全靠它把服务器的验证状态渲染成页面文本;
  • EditForm必须绑定到一个持久化的Model对象——比如在组件里声明一个字段private UserModel _myModel = new();,然后<EditForm Model="@_myModel" ...>,别每次渲染都new一个新的,不然验证状态会丢。

给你一个完整的SSR表单示例,对照着改你的代码:

@page "/register"
<!-- 这里不用加rendermode,默认就是SSR模式 -->

<EditForm Model="@registerModel" OnValidSubmit="HandleRegister">
    <DataAnnotationsValidator />
    <!-- 可选:用ValidationSummary显示所有错误的汇总 -->
    <ValidationSummary Class="text-danger" />

    <div class="mb-3">
        <label class="form-label">用户名</label>
        <InputText @bind-Value="registerModel.Username" Class="form-control" />
        <!-- 对应属性的错误消息容器 -->
        <ValidationMessage For="@(() => registerModel.Username)" Class="text-danger" />
    </div>

    <button type="submit" class="btn btn-primary">注册</button>
</EditForm>

@code {
    // 初始化Model,要作为组件字段,别在方法里临时new
    private RegisterModel registerModel = new();

    private void HandleRegister()
    {
        // 验证通过后的业务逻辑,比如存数据库
    }

    // 带自定义验证的模型类
    public class RegisterModel
    {
        // 可以自定义错误消息,{0}是属性名,{1}是minLength参数
        [MinimumLength(5, ErrorMessage = "{0}长度不能少于{1}个字符")]
        public string Username { get; set; } = string.Empty;
    }
}

最后再给你划个重点:在SSR模式下,表单提交是走传统的服务器渲染流程,Blazor会把验证状态绑定到Model上,然后重新渲染页面显示错误消息。只要你的自定义验证属性符合ValidationAttribute的标准写法(重写FormatErrorMessage),再配合正确的表单组件配置,错误消息就能正常显示了。

备注:内容来源于stack exchange,提问作者Orgaard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 11:03:13