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

修改ASP.NET Core 3.1代码实现文件存入数据库需求

将ASP.NET Core 3.1文件上传从本地文件夹改为存储到数据库

1. 修改实体模型

替换原有的文件模型,新增适合数据库存储的实体,包含文件二进制内容、元数据等字段:

using System;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;

namespace FileUpload.MVC.Models
{
    // 数据库存储用的文件实体
    public class FileEntity
    {
        [Key]
        public int Id { get; set; }
        public string FileName { get; set; }
        public byte[] FileContent { get; set; }
        public string ContentType { get; set; }
        public long FileSize { get; set; }
        public DateTime UploadedAt { get; set; } = DateTime.UtcNow;
    }

    // 视图展示用的模型(避免传递二进制内容)
    public class FileViewModel
    {
        public int Id { get; set; }
        public string FileName { get; set; }
        public long FileSize { get; set; }
        public DateTime UploadedAt { get; set; }
    }

    public class FilesViewModel
    {
        public List<FileViewModel> Files { get; set; } = new List<FileViewModel>();
    }
}

2. 配置数据库上下文

创建或更新AppDbContext,添加文件实体的数据集:

using Microsoft.EntityFrameworkCore;

namespace FileUpload.MVC.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {
        }

        public DbSet<FileEntity> Files { get; set; }
    }
}

在Startup.cs中注册DbContext(以SQL Server为例):

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<AppDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    
    services.AddControllersWithViews();
    
    // 可选:配置大文件上传限制(示例为100MB)
    services.Configure<FormOptions>(options =>
    {
        options.MultipartBodyLengthLimit = 104857600;
    });
}

在appsettings.json添加数据库连接字符串:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=FileUploadDb;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

3. 重写控制器逻辑

注入AppDbContext,替换上传、列表、下载的实现:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FileUpload.MVC.Data;
using FileUpload.MVC.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace FileUpload.MVC.Models
{
    public class TestController : Controller
    {
        private readonly ILogger<TestController> _logger;
        private readonly AppDbContext _dbContext;

        public TestController(ILogger<TestController> logger, AppDbContext dbContext)
        {
            _logger = logger;
            _dbContext = dbContext;
        }

        public async Task<IActionResult> Index()
        {
            var fileEntities = await _dbContext.Files.OrderByDescending(f => f.UploadedAt).ToListAsync();
            var model = new FilesViewModel
            {
                Files = fileEntities.Select(f => new FileViewModel
                {
                    Id = f.Id,
                    FileName = f.FileName,
                    FileSize = f.FileSize,
                    UploadedAt = f.UploadedAt
                }).ToList()
            };
            return View(model);
        }

        [HttpPost]
        public async Task<IActionResult> Index(IFormFile[] files)
        {
            foreach (var file in files)
            {
                if (file == null || file.Length == 0) continue;

                // 读取文件内容到字节数组
                byte[] fileContent;
                using (var memoryStream = new MemoryStream())
                {
                    await file.CopyToAsync(memoryStream);
                    fileContent = memoryStream.ToArray();
                }

                // 检查同名文件并覆盖(可选逻辑)
                var existingFile = await _dbContext.Files.FirstOrDefaultAsync(f => f.FileName == Path.GetFileName(file.FileName));
                if (existingFile != null)
                {
                    _dbContext.Files.Remove(existingFile);
                }

                // 添加新文件实体到数据库
                var fileEntity = new FileEntity
                {
                    FileName = Path.GetFileName(file.FileName),
                    FileContent = fileContent,
                    ContentType = file.ContentType,
                    FileSize = file.Length
                };
                _dbContext.Files.Add(fileEntity);
            }

            await _dbContext.SaveChangesAsync();
            ViewBag.Message = "Files are successfully uploaded";
            return RedirectToAction(nameof(Index));
        }

        public async Task<IActionResult> Download(int id)
        {
            var fileEntity = await _dbContext.Files.FindAsync(id);
            if (fileEntity == null) return Content("File not found");

            return File(fileEntity.FileContent, fileEntity.ContentType, fileEntity.FileName);
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = System.Diagnostics.Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

4. 更新视图(Index.cshtml)

调整下载链接为基于文件ID,新增文件大小格式化:

@model FilesViewModel

@{
    ViewData["Title"] = "File Upload";
}

<h1>File Upload</h1>

@if (!string.IsNullOrEmpty(ViewBag.Message))
{
    <div class="alert alert-success">@ViewBag.Message</div>
}

<form method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label>Select files</label>
        <input type="file" name="files" multiple class="form-control-file" />
    </div>
    <button type="submit" class="btn btn-primary">Upload</button>
</form>

<h2>Uploaded Files</h2>
@if (Model.Files.Count == 0)
{
    <p>No files uploaded yet.</p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>File Name</th>
                <th>Size</th>
                <th>Uploaded At</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var file in Model.Files)
            {
                <tr>
                    <td>@file.FileName</td>
                    <td>@FormatFileSize(file.FileSize)</td>
                    <td>@file.UploadedAt.ToLocalTime().ToString("yyyy-MM-dd HH:mm")</td>
                    <td>
                        <a asp-action="Download" asp-route-id="@file.Id" class="btn btn-sm btn-primary">Download</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
}

@functions {
    private string FormatFileSize(long bytes)
    {
        if (bytes < 1024) return $"{bytes} Bytes";
        else if (bytes < 1048576) return $"{Math.Round(bytes / 1024.0, 2)} KB";
        else if (bytes < 1073741824) return $"{Math.Round(bytes / 1048576.0, 2)} MB";
        else return $"{Math.Round(bytes / 1073741824.0, 2)} GB";
    }
}

5. 初始化数据库

运行EF Core迁移命令创建文件表:

Add-Migration InitialCreate
Update-Database

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:20:50