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

Blazor开发MCQ页面时不同题目上传图片均保存为同一张问题求解

问题根因
  • SfUploader ID冲突:所有动态生成的上传组件使用固定ID UploadFilesMCQ,同页面重复ID的Syncfusion组件会出现绑定错乱,所有上传操作最终都会关联到最后渲染的上传实例,导致所有行读取同一份文件数据。
  • 全局变量覆盖:你当前使用的filesMCQ、contentMCQ、mCQ都是页面级全局变量,每次新增行、上传新文件时,新数据会直接覆盖旧值,之前行对应的文件数据没有被独立存储,最终保存时所有行都读取最后一次上传的内容。
  • 实体与文件未绑定:tMCQ实体没有单独存储对应行的上传文件信息,仅赋值了路径属性,保存时无法匹配到对应行的专属文件流。
修复步骤

1. 给上传组件配置唯一动态ID

在循环渲染MCQ行的代码中,用当前行的唯一标识拼接上传组件ID,避免重复:

@foreach(var item in tblMCQ)
{
    <SfUploader ID="@($"UploadFilesMCQ_{item.MCQ_Id}")" AllowedExtensions=".png,.jpeg,.jpg" >
        <UploaderEvents ValueChange="@(args => onChangeMCQ(args, item))" OnRemove="@(args => onRemoveMCQ(args, item))"></UploaderEvents> 
        <UploaderTemplates>
            <Template Context="HttpContext">
                <td>
                    <img class="upload-image" alt="Preview Image @(HttpContext.Name)" width="100" height="100" 
                         src="@(item.FilesMCQ.Count > 0 ? item.FilesMCQ.Where(f => f.Name == HttpContext.Name)?.FirstOrDefault()?.Path : string.Empty)" />
                </td>
                <td>
                    <div style="padding: 7px; width: 50px;">
                        <h5 title="@(HttpContext.Name)">@(HttpContext.Name)</h5>
                        <i>@(HttpContext.Size) Bytes</i>
                    </div>
                </td>
            </Template>
        </UploaderTemplates>
    </SfUploader>
}

2. 改造tMCQ实体,新增专属文件存储字段

将原来的全局文件存储字段移动到tMCQ类内部,保证每行数据独立存储自己的上传文件:

public class tMCQ
{
    // 原有字段保留
    public int MCQ_Id { get; set; }
    public string MCQDescription { get; set; }
    public string Code { get; set; }
    public string ImagePath { get; set; }

    // 新增每行专属文件存储字段
    public List<fileInfos> FilesMCQ { get; set; } = new List<fileInfos>();
    public MultipartFormDataContent ContentMCQ { get; set; }
}

3. 修改上传事件逻辑,绑定到当前行实例

修改onChangeMCQ方法,接收当前行的tMCQ实例,将上传的文件数据存入当前行的专属字段,不再操作全局变量:

private void onChangeMCQ(UploadChangeEventArgs args, tMCQ currentRow)
{
    currentRow.FilesMCQ.Clear();
    currentRow.ContentMCQ?.Dispose();
    currentRow.ContentMCQ = new MultipartFormDataContent();

    foreach (var file in args.Files)
    {
        currentRow.FilesMCQ.Add(new fileInfos
        {
            Name = file.FileInfo.Name,
            Size = file.FileInfo.Size,
            Path = file.Url
        });
        currentRow.ContentMCQ.Add(new StreamContent(file.OpenReadStream()), file.FileInfo.Name, file.FileInfo.Name);
    }
}

4. 简化AddLine方法,移除全局变量操作

删除页面级的全局filesMCQ、contentMCQ变量,调整AddLine逻辑:

private async void AddLine()
{
    cursor(true);
    tMCQ item = new tMCQ();
    MCQNumber++;
    item.MCQDescription = mCQ.MCQDescription;
    item.MCQ_Id = MCQNumber;
    item.Code = char.ConvertFromUtf32(64 + MCQNumber);
    tblMCQ.Add(item);
    CodeNumber++;
    // 仅清空临时输入变量
    mCQ.MCQDescription = "";
}

5. 调整保存逻辑,逐行处理专属文件

保存时循环遍历每行tMCQ,单独处理对应行的上传文件:

foreach (var item in tblMCQ)
{
    if (item.ContentMCQ != null && item.FilesMCQ.Any())
    {
        string ext = item.FilesMCQ.First().Name.Split('.').Last();
        string FileName = $"{Guid.NewGuid()}.{ext}";
        string savePath = new ExtensionMethods().SaveTo(FileName);
        item.ImagePath = savePath;
        
        using (var ms = new FileStream(savePath, FileMode.Create))
        {
            await item.ContentMCQ.First().CopyToAsync(ms);
        }
        // 处理完释放资源
        item.ContentMCQ.Dispose();
    }
}

内容的提问来源于stack exchange,提问作者Ahtasham ul haq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:36:04