-
-
Notifications
You must be signed in to change notification settings - Fork 383
feat(CardUpload): trigger Validate when delete file #7434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9ecff37
217f906
64ce6b2
1152fa8
448ce78
4db6e97
3ddb84a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| // 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 | ||
|
|
||
| namespace BootstrapBlazor.Components; | ||
|
|
||
| readonly record struct UploadValidateItem(string? Id, string? ErrorMessage); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
|
|
||
| using Microsoft.AspNetCore.Components.Forms; | ||
| using Microsoft.Extensions.Localization; | ||
| using System.Collections; | ||
| using System.Collections.Concurrent; | ||
| using System.Linq.Expressions; | ||
| using System.Reflection; | ||
|
|
@@ -508,7 +509,14 @@ private async Task ValidateAsync(IValidateComponent validator, ValidationContext | |
| else | ||
| { | ||
| // 未选择文件 | ||
| propertyValue = null; | ||
| if (propertyValue is string) | ||
| { | ||
|
|
||
| } | ||
| else if (propertyValue is IEnumerable) | ||
|
Comment on lines
+512
to
+516
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): The empty Previously, |
||
| { | ||
| propertyValue = null; | ||
| } | ||
| ValidateDataAnnotations(propertyValue, context, messages, pi); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,4 @@ | ||||||||||
| // Licensed to the .NET Foundation under one or more agreements. | ||||||||||
| // 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 | ||||||||||
|
|
@@ -42,4 +42,8 @@ public static ValidationResult GetValidationResult(this ValidationContext contex | |||||||||
| var memberNames = string.IsNullOrEmpty(context.MemberName) ? null : new string[] { context.MemberName }; | ||||||||||
| return new ValidationResult(errorMessage, memberNames); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| internal static List<UploadValidateItem> GetInvalidItems(this IReadOnlyCollection<ValidationResult> source, bool isInValidOnAddItem, string? newId) => isInValidOnAddItem | ||||||||||
| ? [new UploadValidateItem() { Id = newId, ErrorMessage = source.First().ErrorMessage }] | ||||||||||
| : source.Select(i => new UploadValidateItem() { Id = i.MemberNames.FirstOrDefault(), ErrorMessage = i.ErrorMessage }).ToList(); | ||||||||||
|
Comment on lines
+47
to
+48
|
||||||||||
| ? [new UploadValidateItem() { Id = newId, ErrorMessage = source.First().ErrorMessage }] | |
| : source.Select(i => new UploadValidateItem() { Id = i.MemberNames.FirstOrDefault(), ErrorMessage = i.ErrorMessage }).ToList(); | |
| ? [new UploadValidateItem(newId, source.First().ErrorMessage)] | |
| : source.Select(i => new UploadValidateItem(i.MemberNames.FirstOrDefault(), i.ErrorMessage)).ToList(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone | ||
|
|
||
| using Microsoft.AspNetCore.Components.Forms; | ||
| using System.ComponentModel.DataAnnotations; | ||
|
|
||
| namespace UnitTest.Components; | ||
|
|
||
|
|
@@ -150,20 +151,77 @@ public void ShowFileSize_Ok() | |
| cut.DoesNotContain("upload-item-file-size"); | ||
| } | ||
|
|
||
| private class Dummy | ||
| { | ||
| [Required] | ||
| public List<UploadFile>? Files { get; set; } | ||
| } | ||
|
|
||
| [Fact] | ||
| public void CardUpload_ValidateForm_Ok() | ||
| public async Task CardUpload_ValidateForm_Ok() | ||
| { | ||
| var foo = new Foo(); | ||
| var invalid = false; | ||
| var foo = new Dummy(); | ||
| var cut = Context.Render<ValidateForm>(pb => | ||
| { | ||
| pb.Add(a => a.Model, foo); | ||
| pb.AddChildContent<CardUpload<string>>(pb => | ||
| pb.AddChildContent<CardUpload<List<UploadFile>>>(pb => | ||
| { | ||
| pb.Add(a => a.Accept, "Image"); | ||
| pb.Add(a => a.Value, foo.Files); | ||
| pb.Add(a => a.ValueChanged, EventCallback.Factory.Create<List<UploadFile>?>(this, v => foo.Files = v)); | ||
| pb.Add(a => a.ValueExpression, Utility.GenerateValueExpression(foo, "Files", typeof(List<UploadFile>))); | ||
| pb.Add(a => a.AllowExtensions, [".jpg"]); | ||
| pb.Add(a => a.ShowDeleteButton, true); | ||
| }); | ||
| pb.Add(a => a.OnValidSubmit, context => | ||
| { | ||
| invalid = false; | ||
| return Task.CompletedTask; | ||
| }); | ||
| pb.Add(a => a.OnInvalidSubmit, context => | ||
| { | ||
| pb.Add(a => a.Value, foo.Name); | ||
| pb.Add(a => a.ValueExpression, foo.GenerateValueExpression()); | ||
| invalid = true; | ||
| return Task.CompletedTask; | ||
| }); | ||
| }); | ||
| cut.Contains("form-label"); | ||
|
|
||
| // 提交表单 | ||
| var form = cut.Find("form"); | ||
| await cut.InvokeAsync(() => form.Submit()); | ||
| Assert.True(invalid); | ||
|
|
||
| var input = cut.FindComponent<InputFile>(); | ||
| await cut.InvokeAsync(async () => | ||
| { | ||
| await input.Instance.OnChange.InvokeAsync(new InputFileChangeEventArgs(new List<MockBrowserFile>() | ||
| { | ||
| new() | ||
| })); | ||
| form.Submit(); | ||
| }); | ||
| Assert.False(invalid); | ||
|
|
||
| // 设置 Disabled 取消校验 | ||
| var upload = cut.FindComponent<CardUpload<List<UploadFile>>>(); | ||
| upload.Render(pb => | ||
| { | ||
| pb.Add(a => a.IsDisabled, true); | ||
| }); | ||
|
|
||
| Assert.DoesNotContain("is-invalid", upload.Markup); | ||
|
|
||
| upload.Render(pb => | ||
| { | ||
| pb.Add(a => a.IsDisabled, false); | ||
| }); | ||
|
|
||
| var items = cut.FindAll(".btn-outline-danger"); | ||
| Assert.Single(items); | ||
| await cut.InvokeAsync(() => items[0].Click()); | ||
|
|
||
| form = cut.Find("form"); | ||
| await cut.InvokeAsync(() => form.Submit()); | ||
|
||
| } | ||
|
|
||
| [Fact] | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This empty code block appears to be intentional but lacks documentation. When the propertyValue is a string type and no files are uploaded, this block does nothing, which means the string value is validated as-is. Consider adding a comment explaining why string values don't need special handling in this case, or if this is incomplete logic that needs to be implemented.