ASP.NET Core中如何在项目其他位置使用Video实体的ContentPath变量值
解决方案
你当前的实现思路存在核心逻辑问题:ContentPath是每个Video实体独有的动态字段,会随不同视频变化,不应该作为全局固定值在Startup中注册为单例,正确实现步骤如下:
步骤1:修改Startup配置
删除原有固定路径的单例注册,改为注册文件存储的根目录即可:
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddDbContext<ServerContext>(opt => opt.UseInMemoryDatabase("Server")); services.AddDbContext<VideoContext>(opt => opt.UseInMemoryDatabase("Video")); // 仅注册存储根目录,不要写死具体文件名 services.AddSingleton(System.IO.Directory.GetCurrentDirectory()); }
步骤2:修改控制器逻辑
控制器注入VideoContext和存储根目录,每次请求时根据视频ID查询对应实体的ContentPath动态使用:
[Route("api/servers/{serverId}/videos")] [ApiController] public class VideosController : ControllerBase { private readonly string _rootPath; private readonly VideoContext _videoContext; public VideosController(VideoContext videoContext, string rootPath) { _videoContext = videoContext; _rootPath = rootPath; } [HttpGet("{id}/binary")] public IActionResult GetBinary(int id) // 此处id类型请和你Video实体的主键类型保持一致 { // 按请求ID查询对应的Video实体 var targetVideo = _videoContext.Videos.Find(id); if (targetVideo == null) { return NotFound("请求的视频不存在"); } // 拼接完整物理路径 var fullFilePath = System.IO.Path.Combine(_rootPath, targetVideo.ContentPath); if (!System.IO.File.Exists(fullFilePath)) { return NotFound("视频文件不存在"); } // 提取文件名作为下载文件名 var downloadFileName = System.IO.Path.GetFileName(targetVideo.ContentPath); return File(System.IO.File.ReadAllBytes(fullFilePath), "application/octet-stream", downloadFileName); } }
额外注意事项
- 需要增加路径安全校验,避免用户传入
../../xxx类的恶意路径触发路径遍历漏洞,确保拼接后的路径始终在允许的存储根目录范围内 - 大文件不要使用
ReadAllBytes加载全部内容到内存,推荐改为FileStream返回降低内存占用 - POST/PUT接口保存
ContentPath时,建议提前校验路径合法性,禁止传入超出业务允许范围的路径
内容的提问来源于stack exchange,提问作者Matheus Reis
相关产品推荐
相关产品推荐

