首页 > 解决方案 > 为什么我不能访问从 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 一样。

测试文件正确添加到 API 本地文件的演示

但是,尝试加载 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 中以访问其中的文件。

就像现在一样,我已经得到了我想要做的事情。

标签: c#.netapi

解决方案


正如@Heinzi 指出的那样,首先是安全问题......

string filePath = form["route"] == "" ? Path.Combine(_hostingEnvironment.WebRootPath, "media") : Path.Combine(_hostingEnvironment.WebRootPath, "media", form["route"]);

如果用户发送 form.route == "../../" 而不是图像,他会更新 appsettings.json 文件怎么办?

如果您打算将此代码发布到生产环境,请检查并记住一点,并确保您只接受图像文件。

另一方面,如果您从不同于 wwwroot 的文件夹中提供静态文件,请使用此配置


推荐阅读