惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
K
Kaspersky official blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Schneier on Security
C
Cybersecurity and Infrastructure Security Agency CISA
Security Archives - TechRepublic
Security Archives - TechRepublic
Hacker News - Newest:
Hacker News - Newest: "LLM"
Cisco Talos Blog
Cisco Talos Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Cyberwarzone
Cyberwarzone
L
LINUX DO - 最新话题
PCI Perspectives
PCI Perspectives
酷 壳 – CoolShell
酷 壳 – CoolShell
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
N
News and Events Feed by Topic
V
Vulnerabilities – Threatpost
T
Troy Hunt's Blog
GbyAI
GbyAI
C
CERT Recently Published Vulnerability Notes
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
量子位
Scott Helme
Scott Helme
月光博客
月光博客
Attack and Defense Labs
Attack and Defense Labs
aimingoo的专栏
aimingoo的专栏
博客园 - 聂微东
Project Zero
Project Zero
G
GRAHAM CLULEY
博客园 - 【当耐特】
Recorded Future
Recorded Future
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
小众软件
小众软件
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
O
OpenAI News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
爱范儿
爱范儿
S
Security @ Cisco Blogs
The Last Watchdog
The Last Watchdog
MongoDB | Blog
MongoDB | Blog
H
Hacker News: Front Page
Latest news
Latest news
P
Proofpoint News Feed

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Blazor SSR Gets Client-Side Validation in .NET 11 Preview 5 — No More Round-Trips Just to Show a Red Border
Vikrant Bagal · 2026-06-13 · via DEV Community

Blazor SSR Gets Client-Side Validation in .NET 11 Preview 5

If you've built Blazor Server-Side Rendering (SSR) forms, you know the pain: a user fills out a form, hits submit, the form posts to the server, the server runs validation, and only then does the user see the "This field is required" message next to the empty email field.

That round-trip latency adds up. It breaks the immediacy users expect from modern web apps.

.NET 11 Preview 5 fixes this. Blazor SSR forms now get instant, in-browser validation feedback — no server required. The server renders your validation rules as metadata, and Blazor's JavaScript enforces them client-side. Same DataAnnotationsValidator component you already use. Zero code changes needed.

Let's break down how it works.


Before .NET 11: The SSR Validation Gap

In .NET 8 and 9, Blazor SSR rendered HTML on the server and sent it down. Validation only ran server-side — on form submission. If a field was invalid, the whole form posted to the server, came back with validation messages, and re-rendered.

Interactive Blazor modes (Server, WebAssembly, Auto) had instant client-side validation because an active SignalR circuit or WASM runtime ran the validation logic locally. But SSR mode — the simplest, most performant option — was left out.

The result? Developers who chose SSR Blazor for its simplicity had to choose between:

  • Accepting the laggy validation UX
  • Adding a second JavaScript validation library (and maintaining two validation rulesets)
  • Re-architecting to use an interactive render mode

None of these are great options.


What Changed in .NET 11 Preview 5

The .NET team shipped two PRs (#66441 and #66420) that bring unobtrusive client-side validation to Blazor SSR forms.

The key insight: The .NET model stays the single source of truth. On form render, the server serializes your DataAnnotations validation rules into HTML metadata attributes. Blazor's JavaScript reads those attributes and applies them client-side — the same approach ASP.NET MVC has used for years with jquery.validate.unobtrusive.

How It Works

  1. Server renders metadata — When an <EditForm> with <DataAnnotationsValidator /> renders in SSR mode, the server emits data-val-* attributes for each field's validation rules (required, string length, regex, compare, email, etc.)

  2. Client enforces — Blazor's built-in JavaScript intercepts form submission and validates fields against the metadata. If a field fails, it shows the ValidationMessage immediately — no POST needed.

  3. Server re-validates on submit — When the form does post to the server (after passing client-side validation), the server validates again as a safety net. Defense in depth.

What You Need

Nothing. The feature is enabled by default for all SSR forms that include the <DataAnnotationsValidator /> component. Both enhanced forms (Enhance) and non-enhanced forms work.


Code Example: Registration Form (SSR)

Here's a standard Blazor SSR registration form with DataAnnotationsValidator. This exact code works with or without client-side validation in .NET 11 Preview 5:

@page "/register"
@using System.ComponentModel.DataAnnotations

<EditForm Model="Model" Enhance FormName="registration" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />

    <div>
        <label for="Email">Email</label>
        <InputText @bind-Value="Model!.Email" id="Email" />
        <ValidationMessage For="() => Model!.Email" />
    </div>

    <div>
        <label for="Password">Password</label>
        <InputText @bind-Value="Model!.Password" id="Password" type="password" />
        <ValidationMessage For="() => Model!.Password" />
    </div>

    <div>
        <label for="ConfirmPassword">Confirm Password</label>
        <InputText @bind-Value="Model!.ConfirmPassword" id="ConfirmPassword" type="password" />
        <ValidationMessage For="() => Model!.ConfirmPassword" />
    </div>

    <button type="submit">Register</button>
</EditForm>

@code {
    [SupplyParameterFromForm]
    private RegistrationModel? Model { get; set; }

    protected override void OnInitialized() => Model ??= new();

    private void HandleValidSubmit()
    {
        // Form is valid — process registration
    }
}

public class RegistrationModel
{
    [Required]
    [EmailAddress]
    public string? Email { get; set; }

    [Required]
    [StringLength(100, MinimumLength = 8)]
    public string? Password { get; set; }

    [Required]
    [Compare("Password")]
    [Display(Name = "Confirm Password")]
    public string? ConfirmPassword { get; set; }
}

In .NET 11 Preview 5, when this form renders, the server emits something like:

<input type="email" id="Email"
       data-val="true"
       data-val-required="The Email field is required."
       data-val-email="The Email field is not a valid email address." />

<span data-valmsg-for="Email" data-valmsg-replace="true"></span>

<input type="password" id="Password"
       data-val="true"
       data-val-required="The Password field is required."
       data-val-length="The Password must be at least 8 characters."
       data-val-length-max="100"
       data-val-length-min="8" />

The JS intercepts the submit, runs these rules on field blur and on submit, and the validation messages appear instantly.


What About Enhanced Forms?

Blazor SSR enhanced forms (those with the Enhance attribute on <EditForm>) use form enhancement — the form posts via fetch and patches the DOM with the response. In previous releases, the validation experience was:

  1. User fills form
  2. User clicks submit
  3. Form posts via fetch
  4. Server validates
  5. Response patches the DOM with validation errors

With .NET 11 Preview 5, enhanced forms also get client-side validation as a first pass — the form validates locally before the fetch even fires. This means:

  • Before .NET 11 P5: Submit → fetch (latency) → validation feedback
  • After .NET 11 P5: Instant validation → submit → fetch → server re-validation

Non-enhanced forms work identically — just without the fetch patching.


Bonus: Async Form Validation

Preview 5 also ships the building blocks for async validation in Blazor forms. You can now register per-field async validation tasks via EditContext.AddValidationTask:

@implements IDisposable

<EditForm EditContext="editContext" OnSubmit="HandleSubmit">
    <InputText @bind-Value="model.Username" />
    @if (editContext.IsValidationPending(() => model.Username))
    {
        <span>Checking availability...</span>
    }
    <ValidationMessage For="() => model.Username" />
    <button type="submit">Register</button>
</EditForm>

@code {
    [Inject] public UserService Users { get; set; } = default!;

    private readonly RegistrationModel model = new();
    private EditContext editContext = default!;
    private ValidationMessageStore messages = default!;

    protected override void OnInitialized()
    {
        editContext = new EditContext(model);
        messages = new ValidationMessageStore(editContext);

        editContext.OnFieldChanged += (_, e) =>
        {
            if (e.FieldIdentifier.FieldName == nameof(model.Username))
            {
                var cts = new CancellationTokenSource();
                editContext.AddValidationTask(e.FieldIdentifier,
                    CheckAsync(e.FieldIdentifier, model.Username, cts.Token), cts);
            }
        };
    }

    private async Task CheckAsync(FieldIdentifier field, string value, CancellationToken ct)
    {
        messages.Clear(field);
        if (await Users.IsUsernameTakenAsync(value, ct))
        {
            messages.Add(field, "Username is taken.");
        }
        editContext.NotifyValidationStateChanged();
    }

    private async Task HandleSubmit() => await editContext.ValidateAsync();

    public void Dispose() => messages?.Clear();
}

The framework tracks pending tasks, cancels superseded ones (when the user types again), and exposes IsValidationPending(field) and IsValidationFaulted(field) for the UI to show spinner states.

Note: The full built-in async validation experience will land in a later preview once the new async DataAnnotations APIs ship. But the foundation is here now.


Bonus: Localized Validation Errors

Preview 5 also adds first-class localization support for validation messages in Blazor forms and Minimal API endpoints:

builder.Services.AddValidation()
    .AddValidationLocalization<ValidationMessages>();

This resolves localized strings from RESX files (or a custom IStringLocalizerFactory) using the ErrorMessage values as keys. You can also configure a programmatic strategy:

builder.Services.AddValidation()
    .AddValidationLocalization<ValidationMessages>(options =>
    {
        options.ErrorMessageKeyProvider = ctx =>
            ctx.Attribute.ErrorMessage ?? $"{ctx.Attribute.GetType().Name}_Error";
    });

Now your [Required] attribute automatically picks up the right language without changing a line of Razor code.


Migration Guide

If you have existing Blazor SSR forms in a .NET 8, 9, or 10 project:

  1. Upgrade the SDK to .NET 11 Preview 5+ (dotnet --version should show 11.0.100-preview.5.*)
  2. Set LangVersion to preview in your .csproj:
<PropertyGroup>
    <TargetFramework>net11.0</TargetFramework>
    <LangVersion>preview</LangVersion>
</PropertyGroup>

  1. That's it. If you use <DataAnnotationsValidator /> in your SSR forms, client-side validation is now active. Test by tabbing off a required field without filling it — you should see the validation message instantly.

Existing Enhanced Forms

Enhanced forms (Enhance) get the same client-side validation automatically. No changes needed.


What This Means for Blazor Developers

This is a meaningful step forward for Blazor SSR. The biggest critique of SSR forms was the validation UX gap compared to interactive modes. With client-side validation, SSR Blazor forms now feel as responsive as traditional JavaScript frameworks — without requiring JavaScript interop, a separate validation library, or giving up the simplicity of static server rendering.

Who benefits most:

  • SSR-first Blazor apps — Public-facing sites, content-heavy apps, and pages where interactivity overhead isn't justified
  • Progressively enhanced forms — Forms that work without JavaScript but feel instant with it
  • Teams migrating from MVC/Razor Pages — The unobtrusive validation pattern will feel familiar
  • Multi-lingual apps — Localized validation messages are now a built-in concern, not an afterthought

Summary

Feature .NET 10 .NET 11 Preview 5
SSR client-side validation ❌ Server-only ✅ Instant in-browser
Async form validation ✅ Building blocks shipped
Localized validation Partial ✅ First-class via AddValidationLocalization
QuickGrid SSR ✅ Sort/page without interactivity
SupplyParameterFromSession ✅ Session-backed component state
Dev setup DevServer ✅ New Gateway dev server

.NET 11 Preview 5 turns Blazor SSR into a viable option for form-heavy applications by closing the validation UX gap. The .NET model stays the source of truth, your existing DataAnnotationsValidator components work unchanged, and the result is instant visual feedback for your users.


Have you tried Blazor SSR in production? Does client-side validation change the calculus for your next project? Drop a comment — I'd love to hear your take.

This post was written with .NET 11 Preview 5. Features may change before the final release.