首页 > 解决方案 > 在 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");
}

有人可以让我知道我做错了什么吗?

编辑:我应该对我的项目的目的更清楚一点。

我要处理三个类ProductCreateProductEditProduct。这些类具有相同的属性,例如Name, Price, etc. 唯一的区别是Product具有字符串ImagePathwhileCreateProductEditProducthave 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 功能时,这不起作用。

标签: c#asp.netblazor

解决方案


在我看来,您的两个项目是在不同的文件夹系统下编译的,但托管在同一个域下(例如,“localhost/A”和“localhost/B”)。从浏览器的角度来看,没有问题。

但是,如果您尝试访问物理系统中的文件,则会出现问题,因为它们具有不同的根路径,并且实际上并没有共享任何文件夹。(这是应该的,因为您不希望 2 个应用程序为控制文件系统而苦苦挣扎)

为什么要直接访问图像文件?你会以某种方式从你的其他项目中操纵它们吗?


推荐阅读