Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 27 additions & 24 deletions src/BootstrapBlazor/Components/ValidateForm/ValidateForm.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,10 +385,6 @@ private void ValidateDataAnnotations(object? value, ValidationContext context, L
var result = rule.GetValidationResult(value, context);
if (result != null && result != ValidationResult.Success)
{
// 查找 resource 资源文件中的 ErrorMessage
var ruleNameSpan = rule.GetType().Name.AsSpan();
var index = ruleNameSpan.IndexOf(attributeSpan, StringComparison.OrdinalIgnoreCase);
var ruleName = ruleNameSpan[..index];
var find = false;
if (!string.IsNullOrEmpty(rule.ErrorMessage))
{
Expand All @@ -400,29 +396,36 @@ private void ValidateDataAnnotations(object? value, ValidationContext context, L
}
}

// 通过设置 ErrorMessage 检索
if (!context.ObjectType.Assembly.IsDynamic && !find
&& !string.IsNullOrEmpty(rule.ErrorMessage)
&& LocalizerFactory.Create(context.ObjectType).TryGetLocalizerString(rule.ErrorMessage, out var msg))
if (!context.ObjectType.Assembly.IsDynamic)
{
rule.ErrorMessage = msg;
find = true;
}
if (!find && !string.IsNullOrEmpty(rule.ErrorMessage)
&& LocalizerFactory.Create(context.ObjectType).TryGetLocalizerString(rule.ErrorMessage, out var msg))
{
// 通过设置 ErrorMessage 检索
rule.ErrorMessage = msg;
find = true;
}

// 通过 Attribute 检索
if (!rule.GetType().Assembly.IsDynamic && !find
&& LocalizerFactory.Create(rule.GetType()).TryGetLocalizerString(nameof(rule.ErrorMessage), out msg))
{
rule.ErrorMessage = msg;
find = true;
}
if (!find && LocalizerFactory.Create(rule.GetType()).TryGetLocalizerString(nameof(rule.ErrorMessage), out msg))
{
// 通过 Attribute 检索
rule.ErrorMessage = msg;
find = true;
}

// 通过 字段.规则名称 检索
if (!context.ObjectType.Assembly.IsDynamic && !find
&& LocalizerFactory.Create(context.ObjectType).TryGetLocalizerString($"{memberName}.{ruleName.ToString()}", out msg))
{
rule.ErrorMessage = msg;
find = true;
if (!find)
{
// 通过 字段.规则名称 检索
// 查找 resource 资源文件中的 ErrorMessage
var ruleNameSpan = rule.GetType().Name.AsSpan();
var index = ruleNameSpan.IndexOf(attributeSpan, StringComparison.OrdinalIgnoreCase);
var ruleName = index == -1 ? ruleNameSpan[..] : ruleNameSpan[..index];
if (LocalizerFactory.Create(context.ObjectType).TryGetLocalizerString($"{memberName}.{ruleName.ToString()}", out msg))
{
rule.ErrorMessage = msg;
find = true;
}
}
}

if (!find)
Expand Down
34 changes: 33 additions & 1 deletion test/UnitTest/Components/ValidateFormTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,27 @@ public async Task Validate_Service_Ok()
var msg = cut.FindComponent<MockInput<string>>().Instance.GetErrorMessage();
Assert.Equal(HasServiceAttribute.Success, msg);
}

[Fact]
public async Task TestService_Ok()
{
// 自定义验证规则没有使用约定 Attribute 结尾单元测试
var foo = new HasService();
var cut = Context.RenderComponent<ValidateForm>(pb =>
{
pb.Add(a => a.Model, foo);
pb.AddChildContent<MockInput<string>>(pb =>
{
pb.Add(a => a.Value, foo.Tag2);
pb.Add(a => a.ValueExpression, Utility.GenerateValueExpression(foo, "Tag2", typeof(string)));
pb.Add(a => a.ValidateRules, [new FormItemValidator(new TestValidateRule())]);
});
});
var form = cut.Find("form");
await cut.InvokeAsync(() => form.Submit());
var msg = cut.FindComponent<MockInput<string>>().Instance.GetErrorMessage();
Assert.Equal("Test", msg);
}

[Fact]
public async Task RequiredValidator_Ok()
Expand Down Expand Up @@ -726,7 +747,7 @@ public void ShowAllInvalidResult_Ok()
private class HasServiceAttribute : ValidationAttribute
{
public const string Success = "Has Service";
public const string Error = "No Service";
private const string Error = "No Service";

protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
Expand All @@ -738,10 +759,21 @@ private class HasServiceAttribute : ValidationAttribute
}
}

private class TestValidateRule : ValidationAttribute
{
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
return new("Test");
}
}

private class HasService
{
[HasService]
public string? Tag { get; set; }

[TestValidateRule]
public string? Tag2 { get; set; }
}

[MetadataType(typeof(DummyMetadata))]
Expand Down