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

ASP.NET Core文件上传入库时如何实现Spinner加载动画/进度条

实现方案

FormData适配的核心坑点是Ajax提交时必须关闭默认的内容编码、数据处理逻辑,同时要带上ASP.NET Core的防伪造令牌,否则会出现IFormFile接收为null、400验证错误等问题,按下面步骤改就能直接跑通:

1. 添加Spinner加载动画DOM

直接在表单外插入默认隐藏的加载遮罩,复用Bootstrap内置样式无需额外写CSS:

<!-- 全屏加载遮罩+Spinner,默认隐藏 -->
<div id="uploadSpinner" class="d-none position-fixed w-100 h-100 top-0 left-0 bg-dark bg-opacity-50 d-flex justify-content-center align-items-center" style="z-index:9999;">
    <div class="spinner-border text-info" role="status">
        <span class="sr-only">加载中...</span>
    </div>
</div>

2. 前端改造:阻止默认表单提交,改用Ajax发送请求

把原有表单的同步提交拦下来,手动构造FormData发异步请求,注意几个必填配置不要写错。把下面JS放在页面底部即可:

@section Scripts {
    <script>
        $(function() {
            // 可选:补Bootstrap文件选择框默认逻辑,选完文件自动显示文件名
            $('.custom-file-input').on('change', function() {
                let fileName = $(this).val().split('\\').pop();
                $(this).next('.custom-file-label').addClass('selected').html(fileName);
            });

            // 绑定表单提交事件
            $('form').on('submit', function(e) {
                // 阻止表单默认跳转提交
                e.preventDefault();
                
                // 校验是否选中文件
                let fileInput = $(this).find('input[name="file"]')[0];
                if (fileInput.files.length === 0) {
                    alert('请先选择xls/xlsx格式的Excel文件');
                    return;
                }

                // 构造FormData对象
                let formData = new FormData();
                // 塞入上传的文件
                formData.append('file', fileInput.files[0]);
                // 塞入防伪造令牌,匹配后端[ValidateAntiForgeryToken]校验
                formData.append('__RequestVerificationToken', $(this).find('input[name="__RequestVerificationToken"]').val());

                // 显示加载动画,禁用提交按钮防止重复点击
                $('#uploadSpinner').removeClass('d-none');
                $('#submit').prop('disabled', true);

                // 发送异步上传请求
                $.ajax({
                    url: $(this).attr('action'),
                    type: 'POST',
                    data: formData,
                    // 以下两个配置是FormData正常提交的核心,不要漏
                    contentType: false,
                    processData: false,
                    success: function(res) {
                        if (res.success) {
                            alert('文件解析完成,数据已成功入库');
                            // 上传成功后跳转到列表页,和原有逻辑一致
                            window.location.href = '/Exposure/Index';
                        } else {
                            alert('上传失败:' + res.message);
                        }
                    },
                    error: function() {
                        alert('网络请求异常,请重试');
                    },
                    complete: function() {
                        // 无论请求成功/失败,都隐藏加载动画、恢复按钮状态
                        $('#uploadSpinner').addClass('d-none');
                        $('#submit').prop('disabled', false);
                    }
                })
            })

            // 修复返回列表按钮的逻辑:原按钮type为submit会触发表单提交,改为普通跳转
            $('button:contains("Back to List")').attr('type', 'button').on('click', function() {
                window.location.href = '/Exposure/Index';
            })
        })
    </script>
}

3. 后端方法微调,返回标准Json结果

原有Excel解析、入库逻辑不用改动,只要把返回值改成前端可识别的Json格式即可:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Upload(IFormFile file)
{
   if(file == null || file.Length == 0)
   {
       return Json(new { success = false, message = "未接收到有效上传文件" });
   }

   try
   {
       // 这里放你原有的Excel解析、数据入库逻辑
       // 示例:await ParseExcelAndSaveData(file);
       
       return Json(new { success = true, message = "上传成功" });
   }
   catch (Exception ex)
   {
       return Json(new { success = false, message = ex.Message });
   }
}

常见踩坑说明

  • 不要手动在Ajax配置里写contentType: 'multipart/form-data',手动设置后浏览器不会自动生成请求边界值boundary,后端IFormFile会直接接收为null
  • processData: false必须配置,否则jQuery会自动把FormData对象转成查询字符串,文件二进制内容会直接丢失
  • 防伪造令牌必须随请求传递,否则方法上的[ValidateAntiForgeryToken]校验不通过会直接返回400错误
  • 加载动画的隐藏逻辑必须放在complete回调里,保证请求出错、超时时也能正常关闭,不会出现页面一直卡加载的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:45:43