diff --git a/src/BootstrapBlazor/Components/ValidateForm/BootstrapBlazorDataAnnotationsValidator.cs b/src/BootstrapBlazor/Components/ValidateForm/BootstrapBlazorDataAnnotationsValidator.cs index 8ff9f18b263..e75d5306d44 100644 --- a/src/BootstrapBlazor/Components/ValidateForm/BootstrapBlazorDataAnnotationsValidator.cs +++ b/src/BootstrapBlazor/Components/ValidateForm/BootstrapBlazorDataAnnotationsValidator.cs @@ -10,7 +10,7 @@ namespace BootstrapBlazor.Components; /// /// BootstrapBlazorDataAnnotationsValidator 验证组件 /// -public class BootstrapBlazorDataAnnotationsValidator : ComponentBase +public class BootstrapBlazorDataAnnotationsValidator : ComponentBase, IDisposable { /// /// 获得/设置 当前编辑数据上下文 @@ -23,12 +23,16 @@ public class BootstrapBlazorDataAnnotationsValidator : ComponentBase /// 获得/设置 当前编辑窗体上下文 /// [CascadingParameter] + [NotNull] private ValidateForm? ValidateForm { get; set; } [Inject] [NotNull] private IServiceProvider? Provider { get; set; } + [NotNull] + private ValidationMessageStore? _message = null; + /// /// 初始化方法 /// @@ -36,12 +40,11 @@ protected override void OnInitialized() { if (ValidateForm == null) { - throw new InvalidOperationException($"{nameof(Components.BootstrapBlazorDataAnnotationsValidator)} requires a cascading " + - $"parameter of type {nameof(Components.ValidateForm)}. For example, you can use {nameof(Components.BootstrapBlazorDataAnnotationsValidator)} " + - $"inside an {nameof(Components.ValidateForm)}."); + throw new InvalidOperationException($"{nameof(BootstrapBlazorDataAnnotationsValidator)} requires a cascading parameter of type {nameof(Components.ValidateForm)}. For example, you can use {nameof(BootstrapBlazorDataAnnotationsValidator)} inside an {nameof(Components.ValidateForm)}."); } - CurrentEditContext.AddEditContextDataAnnotationsValidation(ValidateForm, Provider); + _message = new ValidationMessageStore(CurrentEditContext); + AddEditContextDataAnnotationsValidation(); } /// @@ -49,4 +52,81 @@ protected override void OnInitialized() /// /// internal bool Validate() => CurrentEditContext.Validate(); + + private void AddEditContextDataAnnotationsValidation() + { + CurrentEditContext.OnValidationRequested += OnValidationRequested; + CurrentEditContext.OnFieldChanged += OnFieldChanged; + } + + private void RemoveEditContextDataAnnotationsValidation() + { + CurrentEditContext.OnValidationRequested -= OnValidationRequested; + CurrentEditContext.OnFieldChanged -= OnFieldChanged; + } + + private void OnValidationRequested(object? sender, ValidationRequestedEventArgs args) + { + _ = ValidateModel(CurrentEditContext, _message, Provider); + } + + private void OnFieldChanged(object? sender, FieldChangedEventArgs args) + { + _ = ValidateField(CurrentEditContext, _message, args.FieldIdentifier, Provider); + } + + private async Task ValidateModel(EditContext editContext, ValidationMessageStore messages, IServiceProvider provider) + { + var validationContext = new ValidationContext(editContext.Model, provider, null); + var validationResults = new List(); + await ValidateForm.ValidateObject(validationContext, validationResults); + + messages.Clear(); + foreach (var validationResult in validationResults.Where(v => !string.IsNullOrEmpty(v.ErrorMessage))) + { + foreach (var memberName in validationResult.MemberNames) + { + if (!string.IsNullOrEmpty(memberName)) + { + messages.Add(editContext.Field(memberName), validationResult.ErrorMessage!); + } + } + } + editContext.NotifyValidationStateChanged(); + } + + private async Task ValidateField(EditContext editContext, ValidationMessageStore messages, FieldIdentifier field, IServiceProvider provider) + { + // 获取验证消息 + var validationResults = new List(); + var validationContext = new ValidationContext(field.Model, provider, null) + { + MemberName = field.FieldName, + DisplayName = field.GetDisplayName() + }; + + await ValidateForm.ValidateFieldAsync(validationContext, validationResults); + + messages.Clear(field); + messages.Add(field, validationResults.Where(v => !string.IsNullOrEmpty(v.ErrorMessage)).Select(result => result.ErrorMessage!)); + + editContext.NotifyValidationStateChanged(); + } + + private void Dispose(bool disposing) + { + if (disposing) + { + RemoveEditContextDataAnnotationsValidation(); + } + } + + /// + /// + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } } diff --git a/src/BootstrapBlazor/Extensions/BootstrapBlazorEditContextDataAnnotationsExtensions.cs b/src/BootstrapBlazor/Extensions/BootstrapBlazorEditContextDataAnnotationsExtensions.cs deleted file mode 100644 index 07bda88791f..00000000000 --- a/src/BootstrapBlazor/Extensions/BootstrapBlazorEditContextDataAnnotationsExtensions.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the Apache 2.0 License -// See the LICENSE file in the project root for more information. -// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone - -using Microsoft.AspNetCore.Components.Forms; - -namespace BootstrapBlazor.Components; - -/// -/// BootstrapBlazorEditContextDataAnnotationsExtensions 扩展操作类 -/// -internal static class BootstrapBlazorEditContextDataAnnotationsExtensions -{ - /// - /// 添加数据合规检查 - /// - /// The . - /// - /// - public static EditContext AddEditContextDataAnnotationsValidation(this EditContext editContext, ValidateForm editForm, IServiceProvider provider) - { - var messages = new ValidationMessageStore(editContext); - - editContext.OnValidationRequested += async (sender, eventArgs) => await editForm.ValidateModel(sender as EditContext, messages, provider); - editContext.OnFieldChanged += async (sender, eventArgs) => await editForm.ValidateField(editContext, messages, eventArgs, provider); - return editContext; - } - - private static async Task ValidateModel(this ValidateForm editForm, EditContext? editContext, ValidationMessageStore messages, IServiceProvider provider) - { - if (editContext != null) - { - var validationContext = new ValidationContext(editContext.Model, provider, null); - var validationResults = new List(); - await editForm.ValidateObject(validationContext, validationResults); - - messages.Clear(); - foreach (var validationResult in validationResults.Where(v => !string.IsNullOrEmpty(v.ErrorMessage))) - { - foreach (var memberName in validationResult.MemberNames) - { - if (!string.IsNullOrEmpty(memberName)) - { - messages.Add(editContext.Field(memberName), validationResult.ErrorMessage!); - } - } - } - editContext.NotifyValidationStateChanged(); - } - } - - private static async Task ValidateField(this ValidateForm editForm, EditContext editContext, ValidationMessageStore messages, FieldChangedEventArgs args, IServiceProvider provider) - { - // 获取验证消息 - var validationResults = new List(); - var validationContext = new ValidationContext(args.FieldIdentifier.Model, provider, null) - { - MemberName = args.FieldIdentifier.FieldName, - DisplayName = args.FieldIdentifier.GetDisplayName() - }; - - await editForm.ValidateFieldAsync(validationContext, validationResults); - - messages.Clear(args.FieldIdentifier); - messages.Add(args.FieldIdentifier, validationResults.Where(v => !string.IsNullOrEmpty(v.ErrorMessage)).Select(result => result.ErrorMessage!)); - - editContext.NotifyValidationStateChanged(); - } -}