Skip to content

Commit 22f2e24

Browse files
committed
refactor: 重构客户端验证逻辑
1 parent 2914daf commit 22f2e24

File tree

8 files changed

+54
-33
lines changed

8 files changed

+54
-33
lines changed

src/BootstrapBlazor.Server/Locales/en-US.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3468,7 +3468,7 @@
34683468
"AvatarUploadTips7": "Verify that an example of using a picture box is used in the form",
34693469
"AvatarUploadButtonText": "Submit",
34703470
"AvatarUploadValidateTitle": "ValidateForm",
3471-
"AvatarUploadValidateIntro": "Place it in <code>ValidateForm</code> to integrate automatic data validation function. For details, please refer to <code>ValidateForm</code> component",
3471+
"AvatarUploadValidateIntro": "Place it in <code>ValidateForm</code> to integrate automatic data validation function. For details, please refer to <code>ValidateForm</code> component. In this example, the uploaded file extension is limited to <code>.png, .jpg, .jpeg</code>. An error message will be displayed when uploading other formats. The file size limit is <code>5M</code>. An error message will also be displayed when it exceeds",
34723472
"AvatarUploadAcceptTitle": "Accept",
34733473
"AvatarUploadAcceptIntro": "The component provides <code>Accept</code> property for upload file filtering, in this case the circular avatar box accepts both GIF and JPEG images, sets the <code>Accept='image/gif, image/jpeg'</code> and can be written as: <code>Accept='image/*'</code> if you don't restrict the format of the image. Whether this property is not secure or should be to file format validation using the <b>server-side authentication</b>",
34743474
"UploadsWidth": "The width of the preview box",

src/BootstrapBlazor.Server/Locales/zh-CN.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3468,7 +3468,7 @@
34683468
"AvatarUploadTips7": "验证表单内使用头像框示例",
34693469
"AvatarUploadButtonText": "提交",
34703470
"AvatarUploadValidateTitle": "ValidateForm",
3471-
"AvatarUploadValidateIntro": "放置到 <code>ValidateForm</code> 内集成自动数据验证功能,详情可以参考 <code>ValidateForm</code> 组件",
3471+
"AvatarUploadValidateIntro": "放置到 <code>ValidateForm</code> 内集成自动数据验证功能,详情可以参考 <code>ValidateForm</code> 组件,本例中上传文件扩展名仅限制为 <code>.png, .jpg, .jpeg</code>,上传其他格式时会有错误提示,文件大小限制为 <code>5M</code> 超过时也会有错误提示显示",
34723472
"AvatarUploadAcceptTitle": "Accept",
34733473
"AvatarUploadAcceptIntro": "组件提供了 <code>Accept</code> 属性用于设置上传文件过滤功能,本例中圆形头像框接受 GIF 和 JPEG 两种图像,设置 <code>Accept='image/gif, image/jpeg'</code>,如果不限制图像的格式,可以写为:<code>Accept='image/*'</code>,该属性并不安全还是应该是使用 <b>服务器端验证</b> 进行文件格式验证",
34743474
"UploadsWidth": "预览框宽度",

src/BootstrapBlazor/Components/Upload/AvatarUpload.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
}
1515
@foreach (var item in GetUploadFiles())
1616
{
17-
<div class="@GetItemClassString(item)" id="@item.ValidateId" style="@ItemStyleString">
17+
<div @key="item" class="@GetItemClassString(item)" id="@item.ValidateId" style="@ItemStyleString">
1818
<Avatar Url="@item.PrevUrl" />
1919
@if (!IsDisabled)
2020
{
@@ -49,7 +49,7 @@
4949

5050
@code {
5151
RenderFragment RenderAdd =>
52-
@<div class="@ItemClassString" style="@ItemStyleString">
52+
@<div id="@AddId" class="@GetItemClassString()" style="@ItemStyleString">
5353
<div class="@ActionClassString">
5454
<span class="upload-item-plus">
5555
<i class="@AddIcon"></i>

src/BootstrapBlazor/Components/Upload/AvatarUpload.razor.cs

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,28 @@ public partial class AvatarUpload<TValue>
7878
.AddClassFromAttributes(AdditionalAttributes)
7979
.Build();
8080

81-
private string? GetItemClassString(UploadFile item) => CssBuilder.Default(ItemClassString)
82-
.AddClass("is-valid", !IsDisabled && item.IsValid is true)
83-
.AddClass("is-invalid", !IsDisabled && item.IsValid is false)
84-
.AddClass("is-valid", !IsDisabled && item is { IsValid: null, Uploaded: true, Code: 0 })
85-
.AddClass("is-invalid", !IsDisabled && item is { IsValid: null, Code: not 0 })
86-
.Build();
87-
88-
private string? ItemClassString => CssBuilder.Default("upload-item")
81+
private string? GetItemClassString(UploadFile? item = null) => CssBuilder.Default("upload-item")
8982
.AddClass("is-circle", IsCircle)
90-
.AddClass("is-single", IsMultiple == false)
9183
.AddClass("disabled", IsDisabled)
84+
.AddClass(GetValidStatus(item))
9285
.Build();
9386

87+
private string? GetValidStatus(UploadFile? item = null)
88+
{
89+
if (ValidateForm == null)
90+
{
91+
return null;
92+
}
93+
94+
if (IsDisabled)
95+
{
96+
return null;
97+
}
98+
99+
var state = item?.IsValid ?? IsValid;
100+
return state is true ? "is-valid" : "is-invalid";
101+
}
102+
94103
/// <summary>
95104
/// 获得/设置 预览框 Style 属性
96105
/// </summary>
@@ -127,11 +136,11 @@ protected override void OnParametersSet()
127136
InvalidStatusIcon ??= IconTheme.GetIconByKey(ComponentIcons.AvatarUploadInvalidStatusIcon);
128137

129138
// 头像上传时如果用户没有设置 OnChanged 回调,需要使用内置方法将文件头像转化未 Base64 格式用于预览
130-
OnChange ??= new Func<UploadFile, Task>(async item =>
139+
OnChange ??= async item =>
131140
{
132141
item.ValidateId = $"{Id}_{item.GetHashCode()}";
133142
await item.RequestBase64ImageFileAsync();
134-
});
143+
};
135144
}
136145

137146
/// <summary>
@@ -141,12 +150,24 @@ protected override void OnParametersSet()
141150
protected override bool CheckCanUpload()
142151
{
143152
// 允许多上传
144-
if (IsMultiple == true)
153+
if (IsMultiple)
145154
{
146-
return true;
155+
return !MaxFileCount.HasValue || GetUploadFiles().Count < MaxFileCount;
147156
}
148157

149158
// 只允许单个上传
150159
return UploadFiles.Count == 0;
151160
}
161+
162+
/// <summary>
163+
/// 获得 数据验证客户端 ID
164+
/// </summary>
165+
/// <returns></returns>
166+
protected override string? RetrieveId()
167+
{
168+
var files = GetUploadFiles();
169+
return files.Count == 0 ? $"{Id}_new" : files[0].ValidateId;
170+
}
171+
172+
private string? AddId => GetUploadFiles().Count == 0 ? $"{Id}_new" : null;
152173
}

src/BootstrapBlazor/Components/Upload/ButtonUpload.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public partial class ButtonUpload<TValue>
194194
.Build();
195195

196196
private string? GetItemClassString(UploadFile item) => CssBuilder.Default(ItemClassString)
197-
.AddClass("is-valid", item.Uploaded && item.Code == 0)
197+
.AddClass("is-valid", item is { Uploaded: true, Code: 0 })
198198
.AddClass("is-invalid", item.Code != 0)
199199
.Build();
200200

src/BootstrapBlazor/Components/Upload/CardUpload.razor.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ public partial class CardUpload<TValue>
1919
.AddClass("is-invalid", item.Code != 0)
2020
.Build();
2121
private string? ItemClassString => CssBuilder.Default("upload-item")
22-
.AddClass("is-single", IsMultiple == false)
2322
.AddClass("disabled", IsDisabled)
2423
.Build();
2524

src/BootstrapBlazor/Components/Upload/InputUpload.razor.scss

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,6 @@
115115
cursor: pointer;
116116
}
117117

118-
.upload .upload-body.is-avatar .upload-item.is-single {
119-
margin: 0;
120-
}
121-
122118
.upload .upload-body.is-avatar .upload-item.is-invalid {
123119
border-color: var(--bs-danger);
124120
border-style: solid;

src/BootstrapBlazor/Components/Upload/UploadBase.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,22 +122,27 @@ public abstract class UploadBase<TValue> : ValidateBase<TValue>, IUpload
122122
}
123123

124124
/// <summary>
125-
/// <inheritdoc/>
125+
/// User selects files callback method
126126
/// </summary>
127127
/// <param name="args"></param>
128128
/// <returns></returns>
129129
protected async Task OnFileChange(InputFileChangeEventArgs args)
130130
{
131131
UploadFiles.Clear();
132132
var fileCount = MaxFileCount ?? args.FileCount;
133-
var items = args.GetMultipleFiles(fileCount).Select(f => new UploadFile()
133+
var items = args.GetMultipleFiles(fileCount).Select(f =>
134134
{
135-
OriginFileName = f.Name,
136-
Size = f.Size,
137-
File = f,
138-
FileCount = args.FileCount,
139-
Uploaded = false,
140-
UpdateCallback = Update
135+
var file = new UploadFile()
136+
{
137+
OriginFileName = f.Name,
138+
Size = f.Size,
139+
File = f,
140+
FileCount = args.FileCount,
141+
Uploaded = false,
142+
UpdateCallback = Update
143+
};
144+
file.ValidateId = $"{Id}_{file.GetHashCode()}";
145+
return file;
141146
}).ToList();
142147

143148
foreach (var item in items)
@@ -170,7 +175,7 @@ protected async Task OnFileChange(InputFileChangeEventArgs args)
170175
}
171176
else if (ValueType == typeof(IBrowserFile))
172177
{
173-
CurrentValue = (TValue)(object)items[0].File!;
178+
CurrentValue = (TValue)items[0].File!;
174179
}
175180
else if (ValueType == typeof(string))
176181
{
@@ -269,7 +274,7 @@ public virtual void Reset()
269274
}
270275

271276
/// <summary>
272-
/// 显示/隐藏验证结果方法
277+
/// <inheritdoc/>
273278
/// </summary>
274279
/// <param name="results"></param>
275280
public override void ToggleMessage(IEnumerable<ValidationResult> results)

0 commit comments

Comments
 (0)