You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor循环组件中InputFile的OnChange事件无法识别所属组件问题

问题分析与解决方案

问题根源

  1. 循环组件未指定@key:Blazor在循环渲染组件时,若未提供唯一@key,会复用组件实例,导致事件绑定的上下文混乱,所有上传事件都指向第一个组件实例。
  2. InputFile的ID重复:所有InputFile和对应label使用固定IDinputGroupFile,点击任意按钮都会触发第一个匹配的InputFile。
  3. 事件回调参数传递错误:原代码中EventCallback未正确携带组件ID,且参数解构写法错误,导致无法匹配目标组件。

分步修复

1. 顶级页面:给循环组件添加@key

@page "/testing"

@foreach (var id in testingRepeaterIds)
{
    <TestingRepeater ComponentId="id" @key="id"></TestingRepeater>
}

@code {
    private List<int> testingRepeaterIds = new List<int> { 1, 2, 3 };
}
  • 作用:让Blazor精准跟踪每个TestingRepeater实例,避免复用导致的上下文混乱。

2. TestUpload组件:修复ID重复与回调参数

<div class="custom-file">
    <InputFile @key=@(_inputFileId) OnChange=@LoadFiles accept="image/png, image/jpg, image/jpeg"
               style="width: 0px;" multiple class="custom-file-input d-none" id="@_inputFileId" />
    <label class="rz-button rz-button-md rz-variant-flat rz-dark rz-shade-dark" for="@_inputFileId">Choose File(s)</label>
</div>

@code {
    [Parameter] public EventCallback<(List<AttachmentDto> Files, int EntityId)> OnChange { get; set; }
    [Parameter] public int EntityId { get; set; }

    private List<AttachmentDto> loadedFiles = new();
    private bool isLoading;
    private string _inputFileId = Guid.NewGuid().ToString();

    private async Task LoadFiles(InputFileChangeEventArgs e)
    {
        isLoading = true;
        loadedFiles.Clear(); // 清空历史文件,避免重复添加

        foreach (var file in e.GetMultipleFiles())
        {
            var uploadedFile = new AttachmentDto
            {
                DiskName = Path.Combine("uploads", file.Name),
                FileName = file.Name,
                FileSize = file.Size,
                FileType = file.ContentType,
            };

            loadedFiles.Add(uploadedFile);
        }

        await OnChange.InvokeAsync((loadedFiles, EntityId));
        isLoading = false;
    }
}
  • 动态生成InputFile的ID并绑定到label,解决ID重复问题。
  • 修改EventCallback为元组类型,同时传递文件列表与组件ID,确保回调能匹配目标组件。
  • 每次上传前清空文件列表,避免重复添加历史文件。

3. TestingRepeater组件:修正回调逻辑

<TestUpload OnChange="@((args) => LinkFilesToComponent(args.Files, args.EntityId))" EntityId="@ComponentId" />

<RadzenDataGrid @ref="attachmentGrid" AllowSorting="true" PagerHorizontalAlign="HorizontalAlign.Left" ColumnWidth="140px"
                Data="@attachedFiles" TItem="AttachmentDto"
                LogicalFilterOperator="LogicalFilterOperator.Or" Responsive="true">
    <Columns>
        <RadzenDataGridColumn TItem="AttachmentDto" Property="FileName" Title="Name">
            <Template Context="attachment">
                <RadzenTextBox @bind-Value="attachment.FileName" class="w-100" />
            </Template>
        </RadzenDataGridColumn>
    </Columns>
</RadzenDataGrid>


@code {
    [Parameter] public int ComponentId { get; set; }

    private RadzenDataGrid<AttachmentDto> attachmentGrid;

    private List<AttachmentDto> attachedFiles = new List<AttachmentDto>();

    private async Task LinkFilesToComponent(List<AttachmentDto> files, int entityId)
    {
        if (entityId == ComponentId)
        {
            attachedFiles.AddRange(files);
            await attachmentGrid.ReloadAsync(); // 使用异步重载方法,符合Blazor异步规范
        }
    }
}
  • 修正回调参数的解构方式,正确接收文件列表与组件ID。
  • 将async void改为async Task,避免异步操作潜在的异常问题。
  • 使用AddRange替代循环Add,简化代码逻辑。

4. AttachmentDto:修正无效特性

public class AttachmentDto
{
    [MaxLength(1000)]
    public string FileName { get; set; }
    [MaxLength(1000)]
    public string FileType { get; set; }
    public long FileSize { get; set; } // 移除无效的MaxLength特性
    [MaxLength(1000)]
    public string DiskName { get; set; }
}
  • MaxLength特性对long类型无效,直接移除。

内容的提问来源于stack exchange,提问作者Hannah Hayes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:35:35