修改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
相关产品推荐
相关产品推荐

