当前位置:首页 > 行业动态 > 正文

如何用C将文件高效上传至数据库?

在C#中可通过FileStream读取文件流,转换为字节数组后,使用ADO.NET参数化方式将数据存入数据库的varbinary字段,结合SqlCommand与SqlParameter实现安全上传,支持大文件分块处理提升性能,同时防范SQL注入风险。

核心流程与技术选型

实现原理
文件上传至数据库的本质是将文件转换为二进制数据(byte[])后,通过SQL语句存储到数据库的varbinary(MAX)image类型字段中,读取时再通过反向转换还原文件。

技术栈

  • 后端框架:ASP.NET Core(推荐6.0+)
  • 数据库:SQL Server(兼容MySQL、PostgreSQL方案)
  • 前端:HTML5 + JavaScript(支持异步上传)

分步骤实现指南

步骤1:数据库表设计

CREATE TABLE FileStorage (
    FileId INT PRIMARY KEY IDENTITY(1,1),
    FileName NVARCHAR(255) NOT NULL,
    FileType NVARCHAR(50) NOT NULL,
    FileData VARBINARY(MAX) NOT NULL,
    UploadTime DATETIME DEFAULT GETDATE()
);

步骤2:前端上传页面(HTML)

<form id="uploadForm" enctype="multipart/form-data">
    <input type="file" id="fileInput" name="uploadedFile" />
    <button type="button" onclick="uploadFile()">上传</button>
</form>
<div id="progressBar" style="display:none;">上传进度:<span id="progressPercent">0%</span></div>
<script>
async function uploadFile() {
    const formData = new FormData(document.getElementById('uploadForm'));
    const progressBar = document.getElementById('progressBar');
    progressBar.style.display = 'block';
    try {
        const response = await fetch('/api/Upload', {
            method: 'POST',
            body: formData,
            headers: { 'X-Requested-With': 'XMLHttpRequest' }
        });
        alert(response.ok ? '上传成功' : '上传失败');
    } catch (error) {
        console.error('Error:', error);
    }
}
</script>

步骤3:C#后端处理(ASP.NET Core)

[ApiController]
[Route("api/[controller]")]
public class UploadController : ControllerBase
{
    private readonly IConfiguration _config;
    public UploadController(IConfiguration config)
    {
        _config = config;
    }
    [HttpPost]
    public async Task<IActionResult> UploadFile(IFormFile uploadedFile)
    {
        // 验证文件有效性
        if (uploadedFile == null || uploadedFile.Length == 0)
            return BadRequest("未选择文件");
        if (uploadedFile.Length > 50 * 1024 * 1024) // 限制50MB
            return BadRequest("文件过大");
        // 允许的文件类型白名单
        var allowedTypes = new[] { "image/jpeg", "application/pdf" };
        if (!allowedTypes.Contains(uploadedFile.ContentType))
            return BadRequest("不支持的文件类型");
        try
        {
            using var memoryStream = new MemoryStream();
            await uploadedFile.CopyToAsync(memoryStream);
            byte[] fileBytes = memoryStream.ToArray();
            using (SqlConnection conn = new SqlConnection(_config.GetConnectionString("DefaultConnection")))
            {
                await conn.OpenAsync();
                var cmd = new SqlCommand(
                    "INSERT INTO FileStorage (FileName, FileType, FileData) VALUES (@name, @type, @data)",
                    conn);
                cmd.Parameters.AddWithValue("@name", uploadedFile.FileName);
                cmd.Parameters.AddWithValue("@type", uploadedFile.ContentType);
                cmd.Parameters.AddWithValue("@data", fileBytes);
                await cmd.ExecuteNonQueryAsync();
            }
            return Ok();
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"服务器错误:{ex.Message}");
        }
    }
}

安全防护策略

  1. 输入验证

    • 使用白名单机制限制文件类型(避免仅依赖扩展名)
    • 设置文件大小上限(Web.config中同时配置maxAllowedContentLength
    • 重命名存储文件名(避免路径遍历攻击)
  2. SQL注入防护

    • 使用参数化查询(如上例所示)
    • 禁止拼接SQL语句
  3. XSS防御

    • 对前端输入的文件名进行HTML编码
    • 设置响应头X-Content-Type-Options: nosniff
  4. 敏感数据隔离

    • 重要文件建议单独存储加密库
    • 使用Windows身份验证连接数据库

性能优化建议

  1. 异步处理

    • 全程使用async/await异步编程模型
    • 启用响应压缩(AddResponseCompression)
  2. 分块上传

    // 前端使用Blob.slice()分片
    // 后端合并分片后存储
  3. 数据库优化

    • 定期归档历史文件
    • 对FileId建立聚集索引
    • 启用FILESTREAM特性(SQL Server专用)
  4. 缓存策略

    • 对频繁访问的小文件设置内存缓存
    • 使用OutputCacheAttribute缓存文件元数据

延伸方案对比

方案 优点 缺点
直接存数据库 数据一致性高
备份恢复方便
数据库压力大
扩展性有限
文件系统存储 性能高
成本低
需要维护文件路径
迁移复杂
云存储OSS 扩展性强
自带CDN
依赖第三方服务
成本增加

测试与验证

  1. 单元测试要点

    • 模拟10MB/100MB/1GB文件上传
    • 并发上传测试(使用LoadRunner或JMeter)
    • 异常文件类型拒绝测试
  2. 验证方法

    SELECT TOP 1 FileName, DATALENGTH(FileData)/1048576 AS SizeMB 
    FROM FileStorage 
    ORDER BY FileId DESC

引用说明
本文代码示例参考自Microsoft Docs官方文档,安全建议符合OWASP Top 10标准,数据库优化方案基于SQL Server Best Practices Guide。

0