RadzenDataAnnotationValidator: error message not updated when transitioning between invalid states

Fix #2519
This commit is contained in:
Vladimir Enchev
2026-04-08 16:01:44 +03:00
parent f9cde357d6
commit 0d4c846386
2 changed files with 84 additions and 1 deletions

View File

@@ -0,0 +1,81 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;
using Bunit;
using Microsoft.AspNetCore.Components;
using Xunit;
namespace Radzen.Blazor.Tests
{
public class DataAnnotationValidatorTests
{
class Model
{
[Required(ErrorMessage = "Name is required.")]
[StringLength(15, MinimumLength = 4, ErrorMessage = "Name must be between 4 and 15 characters.")]
public string Name { get; set; }
}
private static IRenderedComponent<RadzenTemplateForm<Model>> RenderForm(TestContext ctx, Model model)
{
return ctx.RenderComponent<RadzenTemplateForm<Model>>(parameters => parameters
.Add(p => p.Data, model)
.Add(p => p.ChildContent, editContext => builder =>
{
Expression<Func<string>> valueExpression = () => model.Name;
builder.OpenComponent<RadzenTextBox>(0);
builder.AddAttribute(1, "Name", "Name");
builder.AddAttribute(2, "Value", model.Name);
builder.AddAttribute(3, "ValueChanged", EventCallback.Factory.Create<string>(model, v => model.Name = v));
builder.AddAttribute(4, "ValueExpression", valueExpression);
builder.CloseComponent();
builder.OpenComponent<RadzenDataAnnotationValidator>(5);
builder.AddAttribute(6, "Component", "Name");
builder.CloseComponent();
}));
}
[Fact]
public void DataAnnotationValidator_Updates_Message_When_Transitioning_Between_Invalid_States()
{
using var ctx = new TestContext();
var model = new Model();
var form = RenderForm(ctx, model);
// Trigger validation with empty value → [Required] fails.
form.InvokeAsync(() => form.Instance.EditContext.Validate());
Assert.Contains("Name is required.", form.Markup);
Assert.DoesNotContain("Name must be between 4 and 15 characters.", form.Markup);
// Change value to a single character → [Required] passes, [StringLength] fails.
// IsValid remains false, but Text should change and view should re-render.
model.Name = "a";
form.InvokeAsync(() => form.Instance.EditContext.Validate());
Assert.Contains("Name must be between 4 and 15 characters.", form.Markup);
Assert.DoesNotContain("Name is required.", form.Markup);
}
[Fact]
public void DataAnnotationValidator_Clears_Message_When_Value_Becomes_Valid()
{
using var ctx = new TestContext();
var model = new Model();
var form = RenderForm(ctx, model);
form.InvokeAsync(() => form.Instance.EditContext.Validate());
Assert.Contains("Name is required.", form.Markup);
model.Name = "valid name";
form.InvokeAsync(() => form.Instance.EditContext.Validate());
Assert.DoesNotContain("Name is required.", form.Markup);
Assert.DoesNotContain("Name must be between 4 and 15 characters.", form.Markup);
}
}
}

View File

@@ -128,6 +128,8 @@ namespace Radzen.Blazor
if (component.FieldIdentifier.FieldName != null)
{
var previousIsValid = IsValid;
var previousText = Text;
IsValid = Validate(component);
messages?.Clear(component.FieldIdentifier);
@@ -137,7 +139,7 @@ namespace Radzen.Blazor
messages?.Add(component.FieldIdentifier, Text);
}
if (previousIsValid != IsValid)
if (previousIsValid != IsValid || (!IsValid && previousText != Text))
{
EditContext?.NotifyValidationStateChanged();
}