diff --git a/docs/en/framework/ui/blazor/forms-validation.md b/docs/en/framework/ui/blazor/forms-validation.md index f46ce6fb81..d8acb51776 100644 --- a/docs/en/framework/ui/blazor/forms-validation.md +++ b/docs/en/framework/ui/blazor/forms-validation.md @@ -59,7 +59,7 @@ _The example is provided by official Blazorise documentation._ {{if BlazorUI == "MudBlazor"}} -ABP Blazor UI built on top of [MudBlazor](https://mudblazor.com) uses MudBlazor's built-in form components and validation infrastructure. MudBlazor integrates with ASP.NET Core's `DataAnnotations` and supports custom validation through `IValidationRule`, `Func>`, or fluent validators. +ABP Blazor UI built on top of [MudBlazor](https://mudblazor.com) uses MudBlazor's built-in form components and validation infrastructure. MudBlazor accepts a `ValidationAttribute` (e.g. `[Required]`, `[EmailAddress]` from ASP.NET Core's `DataAnnotations`) on the input's `Validation` parameter, plus custom `Func` / `Func>` delegates. FluentValidation can be plugged in the same way. ## Sample diff --git a/docs/en/tutorials/book-store/part-02.md b/docs/en/tutorials/book-store/part-02.md index 9fd333185d..429d7ec17c 100644 --- a/docs/en/tutorials/book-store/part-02.md +++ b/docs/en/tutorials/book-store/part-02.md @@ -660,7 +660,7 @@ Open the `Books.razor` and replace the content as the following: - @L[$"Enum:BookType.{context.Item.Type}"] + @L[$"Enum:BookType.{(int)context.Item.Type}"] ? _renderedParameterNamesCache; + private HashSet RenderedParameterNames => + _renderedParameterNamesCache ??= (DocumentPreferences?.Parameters?.Select(p => p.Name).ToHashSet() ?? new HashSet()); + public virtual bool IsParameterVisible(DocumentParameterDto parameter) { if (parameter.DependsOn == null || parameter.DependsOn.Count == 0) @@ -97,11 +101,14 @@ namespace Volo.Docs.Pages.Documents.Project return true; } - var renderedKeys = DocumentPreferences?.Parameters?.Select(p => p.Name).ToHashSet() ?? new HashSet(); - - // A rule passes if it's malformed/irrelevant (fail-open) OR the current value matches the allow-list. + // Per-rule semantics: + // - rule.Value == null : malformed list, skip the rule (fail-open) + // - key not in current document : rule references an unknown parameter, skip (fail-open) + // - rule.Value.Count == 0 : explicit empty allow-list, hide the parameter (author intent: "never show") + // - current value not in allow-list: hide + // - current value in allow-list : pass this rule return parameter.DependsOn.All(rule => - rule.Value == null || !renderedKeys.Contains(rule.Key) // skip malformed / unknown-key rules + rule.Value == null || !RenderedParameterNames.Contains(rule.Key) || (rule.Value.Count > 0 && UserPreferences.TryGetValue(rule.Key, out var current) && rule.Value.Contains(current)));