c# - 为什么我不能访问从 POST 请求中以编程方式添加的静态文件?
问题描述
我正在尝试制作一个基本的.NET API 来管理媒体(图像和视频)的集合。
我已将 webroot 配置为一个名为“site”的文件夹,并且在该文件夹中是一个名为“media”的文件夹,其中存储了这些文件。我可以通过加载 https://localhost:5001/site/media/smush.jpg 访问保存在 /site/media/Smush.jpg 中的测试媒体文件 - 这可以按预期提供图像。
我创建了一个从前端接收包含表单数据的 POST 请求的方法,该方法使用文件流将文件保存到 webroot,代码如下:
[HttpPost]
[Route("/media/add")]
public async Task<HttpResponseMessage> MediaAdd()
{
try
{
//get the form
var form = HttpContext.Request.Form;
//if there's a route, add it into the filepath, otherwise leave it out and have the filepath go straight to media (this prevents an exception if route is blank)
string filePath = form["route"] == "" ? Path.Combine(_hostingEnvironment.WebRootPath, "media") : Path.Combine(_hostingEnvironment.WebRootPath, "media", form["route"]);
//get the first (should be only) image - DO WE WANT TO BE ABLE TO ADD MULTIPLE IMAGES? PROBABLY TBH
IFormFile image = form.Files.First();
if (image.Length > 0)
{
//check the directory exists - create it if not
if (!Directory.Exists(filePath)) {
Directory.CreateDirectory(filePath);
}
using (Stream fileStream = new FileStream(Path.Combine(filePath, form["filename"]), FileMode.Create))
{
await image.CopyToAsync(fileStream);
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
else {
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
catch (Exception e)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
我的前端提交了一个路由、文件名和媒体文件,这用于保存图像。这一切都很好;我可以使用路径“test”和名称“test.jpg”提交图像,API 将文件正确存储在 /site/media/test/test.jpg。我可以在解决方案中查看文件并查看图像的预览,就像使用 Smush.jpg 一样。
但是,尝试加载 https://localhost:5001/site/media/test/test.jpg 会导致 404。为什么会这样?我是否可以不通过代码将文件添加到 webroot 中,并让它们作为静态文件访问,就像我将它们添加到我的 IDE 中的解决方案一样?有没有其他的方法来处理这个?
我正在使用 .NET 5.0,并且
app.UseStaticFiles();
在Configure()
Startup.cs 中。
抱歉,如果这是重复的,但我找不到其他类似的东西。
编辑: 再次检查时,似乎不是我的文件位于 https://localhost:5001/site/media 中,而是位于 https://localhost:5001/media 中。我不确定我之前如何能够在 https://localhost:5001/site/media/Smush.jpg 访问 Smush.jpg。
似乎 webroot 没有包含在 URL 中以访问其中的文件。
就像现在一样,我已经得到了我想要做的事情。
解决方案
正如@Heinzi 指出的那样,首先是安全问题......
string filePath = form["route"] == "" ? Path.Combine(_hostingEnvironment.WebRootPath, "media") : Path.Combine(_hostingEnvironment.WebRootPath, "media", form["route"]);
如果用户发送 form.route == "../../" 而不是图像,他会更新 appsettings.json 文件怎么办?
如果您打算将此代码发布到生产环境,请检查并记住这一点,并确保您只接受图像文件。
另一方面,如果您从不同于 wwwroot 的文件夹中提供静态文件,请使用此配置
推荐阅读
- java - Maven项目中的dll放在哪里
- c# - 在 C# 中使用 iso-8859-1 编码“–”
- light-4j - 如何在处理程序请求方法中解析动态路径参数?
- firebase - public FirebaseUser getCurrentUser() 是如何工作的?
- laravel - 如何在 Laravel 中编译 Bootstrap 主题的 Scss 文件
- wordpress - 是否可以为每个用户设置货币?
- android - 当我尝试在 Play 商店上传我的 Voip 应用程序时出现错误
- react-native - React Navigation:如何在按下 TouchableOpacity 时传递道具并导航到其他屏幕
- android - 如何使用 DragListener 收听拖动,但将点击传递到下面的视图?
- python-3.x - 为什么我使用 tensorflow 进行的 DQN 训练每次迭代都会变慢?