c# - 在 ASP.NET 上读取静态文件
问题描述
我正在使用具有多个项目的解决方案,并且在访问我当前所在项目之外的项目时遇到问题。这是我的代码库的一个非常简化的结构:
-ProjectA
-Pages
Index.razor
-ProjectB
- Images
-image.jpg
我在使用 Blazor Server 的 ProjectA 上,我需要在 ProjectB 中读取我的目录之外的图像。我使用以下代码创建了一个静态文件:
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), @"./../ProjectB/Images/")),
RequestPath = new PathString("/MyImages")
});
问题是,当我在 html img 标记中使用“/MyImages”后跟文件名时,它工作正常,我可以在 ProjectB 中查看任何图像。但是,当我使用 System.IO 代码时,这不起作用,例如:
@code{
File.ReadAllBytes("/MyImages/image.jpg");
}
有人可以让我知道我做错了什么吗?
编辑:我应该对我的项目的目的更清楚一点。
我要处理三个类Product
,CreateProduct
和EditProduct
。这些类具有相同的属性,例如Name, Price, etc
. 唯一的区别是Product
具有字符串ImagePath
whileCreateProduct
和EditProduct
have IFormFile Image
。
当我想创建一个新产品时,我读取名称、价格等字符串值,然后对于图像,我使用InputFile
它给我一个IBrowserFile
,做一些基本的转换过程,IFormFile
然后将它发布为一个CreateProduct
. 在后端,API 将 IFormFile 存储在文件系统(又名 ProjectB)中,然后Product
在具有 ImagePath 的 DB 中创建一条记录。
这是此过程的代码片段:
[HttpPost]
public async Task<ActionResult<Product>> PostProduct([FromForm] CreateProduct model)
{
try
{
if (!ModelState.IsValid)
return BadRequest();
// This function helpers.UploadFiles will just write the file to the file system, then return the url
// For example, it'll return "/product_1/image.jpg"
var ProductImagePath = await _helpers.UploadFiles(model.Image);
var product = new Product
{
//news
Name = model.Name,
Price = model.Price,
ImagePath = ProductImagePath,
CreatedDate = DateTime.Now
};
_context.Product.Add(Product);
await _context.SaveChangesAsync();
这就是它在前端的样子:
// Converting my IBrwserFile(imageFile) to bytes so that it can be posted as IForm (Probably could do it better but that's an issue for another day)
using Stream filestream = imageFile.OpenReadStream(1024 * 1024 * 15);
using MemoryStream ms = new();
await filestream.CopyToAsync(ms);
byte[] productImage = ms.ToArray();
var formContent = new MultipartFormDataContent
{
{new StringContent("SomeProductName"),"Name"},
{new StringContent("SomeProductPrice"),"Price" },
{
new ByteArrayContent(productImage), "Image", fileName
},
};
await client.PostAsync("Product/", formContent);
我的 PUT 请求遵循相同的结构。棘手的部分是EditProduct
场景。我首先必须做一个 GET 请求并接收Product
只有图像路径的实例。编辑我的产品需要两种情况:
场景一:
1- Make a GET request for the `Product` class which has the image path
2- View all information including the image on the browser using <img src="ImagePath">
3- Decide to use a different image, which then I just call InputFile
4- Process InputFile and convert it to IFormFile
5- Make a PUT request and post the updated information to `EditForm` class
这很好。但是在场景 2 中:
1- Steps 1 & 2 as before
2- Decide not to change the image, but change other stuff like the Name and price
3- ????
现在我需要发出一个 PUT 请求,但由于我没有使用 InputFile,所以我没有可以发送到 PUT 类请求的 IFormFile EditForm
。为了使 PUT 过程正常工作,我需要读取从 ImagePath 获取的图像,File.ReadAllBytes
然后将其读取到内存中并将其转换为IFormFile
.
正如我在开始时提到的,我可以使用<img src="/MyImages/@imagePath />
,/MyImages
作为我在 Startup.cs 上创建的静态文件路径来查看图像。当我将它应用于File.ReadAllBytes
或任何其他 IO 功能时,这不起作用。
解决方案
在我看来,您的两个项目是在不同的文件夹系统下编译的,但托管在同一个域下(例如,“localhost/A”和“localhost/B”)。从浏览器的角度来看,没有问题。
但是,如果您尝试访问物理系统中的文件,则会出现问题,因为它们具有不同的根路径,并且实际上并没有共享任何文件夹。(这是应该的,因为您不希望 2 个应用程序为控制文件系统而苦苦挣扎)
为什么要直接访问图像文件?你会以某种方式从你的其他项目中操纵它们吗?
推荐阅读
- ruby - 如何在一个动作中使用变量到另一个动作
- python - 如果连接的组合是素数,则接受用户输入并打印
- amazon-web-services - 如何使用 Cloudwatch Event 执行 Lambda 代理集成
- mongodb - 从字符串 Mongodb 的末尾删除子字符串
- couchdb - 如何从超级账本结构中查看或检索数据
- sql - Pivot sql 输出 - Google sql 面试题
- laravel - 访问 Laravel 中的许多页面后重定向到预期的 url
- java - 使用 spring Web Client 命中 https 休息服务
- python - 如何让乌龟遵循我的 IF 语句
- python-3.x - 我可以在使用 urllib3 和 socks 代理时设置一个超时值吗