首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的ASP.NET核心应用程序中的图片会覆盖在我的本地环境中,而不是当我上传到Azure时呢?

为什么我的ASP.NET核心应用程序中的图片会覆盖在我的本地环境中,而不是当我上传到Azure时呢?
EN

Stack Overflow用户
提问于 2021-02-22 17:12:52
回答 1查看 149关注 0票数 0

在我的ASP.NET核心3.1Web应用程序中,我允许用户上传存储在应用程序内部本地目录中的图像。虽然使用Azure上的blob存储可以提供更好的服务,但这个特定的项目要求将blob存储在本地,所以我必须使用它:

代码语言:javascript
复制
wwwroot/images/products/whatever_id/whatever_name.jpg

代码语言:javascript
复制
wwwroot/images/companies/whatever_id/whatever_name.jpg

当用户上传图像时,图像的处理由ImageSharp从SixLabors处理,其中图像被调整了几次大小,以便跨平台使用,并保存到由Id分隔的相对目录中。

代码语言:javascript
复制
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

问题

我面临的问题是,虽然这个过程在本地测试我的应用程序时有效,但是当我将我的应用程序部署到Azure时,它不起作用,并且没有任何类型的错误报告返回。这让我在试图弄清楚到底发生了什么的时候,变得干干净净。

假设

由于这个问题的性质和这些图像的位置,我只能假设出于安全原因,它会阻止覆盖目录中的图像,或者可能是ImageSharp库本身。

需要注意的是,当目录不存在时,产品的实际创建和图像的添加,因此,一个新的产品,完美地工作。只有当你试图覆盖图像时,它才不起作用。

这是我的代码,我已经删除了所有不必要的元素,留下了图像处理的特定代码。

编辑(视图)

代码语言:javascript
复制
@model Products
<form asp-action="Edit" asp-controller="Products" method="POST" enctype="multipart/form-data">
    <div class="card m-4">
        <div class="card-header">
            <h3 class="card-title">Add Product</h3>
        </div>
        <div class="card-body">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-md-4">
                        <div class="form-group">
                            <label>Product Images</label>                         
                            <kendo-upload name="ProductImages" multiple="true" show-file-list="true">
                            </kendo-upload>
                        </div>
                    </div>                        
                </div>              
                <div class="row">
                    <div class="col">
                        <button type="submit" class="btn btn-purple">Submit</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</form>

Edit(Controller)

代码语言:javascript
复制
[HttpPost]
public IActionResult Edit(Products product)
{
    if (ModelState.IsValid && product != null)
    {
        try
        {
            //Process the Images
            if (product.ProductImages != null)
            {
                ProcessImages(product, product.Id);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return RedirectToAction("Index");
    }
    return View();
}

ProcessImages(Stream)

代码语言:javascript
复制
private readonly int[] sizeArray = new int[] { 700, 350, 150 };

public Stream ProcessImages(Products model, int? id)
{
    try
    {
        //Get the images and define the directory structure
        var images = model.ProductImages;
        var root = _env.WebRootPath;
        var folderName = Path.Combine(root, "images", "products", id.ToString());

        //If the ID Directory doesn't exist, create it first.
        if (!Directory.Exists(folderName))
        {
            Directory.CreateDirectory(folderName);
        }
        //Interate over the images and process them
        foreach (var item in images)
        {
            foreach (var imageSize in sizeArray)
            {
                string imageSizeName = "image" + imageSize + ".jpg";
                string fullPath = Path.Combine(folderName, imageSizeName);
                //Create the stream and process the image
                using FileStream fileStream = new FileStream(fullPath, FileMode.Create);

                try
                {
                    Stream inStream = item.OpenReadStream();
                    using Image image = Image.Load(inStream);
                    int width = imageSize;
                    int height = 0;
                    var clone = image.Clone(i => i.Resize(width, height));
                    clone.SaveAsJpeg(fileStream);
                    inStream.Position = 0;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
    }
    catch (Exception ex)
    {
       Console.WriteLine(ex.Message);
    }
    return (null);
}

如您所见,有一个大小数组,其中定义了我们需要的大小,然后循环处理。我们创建文件名并将其保存为jpg。高度设置为0,以便在定义宽度时自动设置它,然后重置流。

Products.cs(model)

代码语言:javascript
复制
    public class Products : BaseEntity
    {        
        public string Title { get; set; }

        [NotMapped]
        public IFormFileCollection ProductImages { get; set; }

    }

所以,问题仍然是,为什么我不能覆盖我的图像一旦我的应用程序生活在Azure?这是一个Azure安全问题,类似于ImageSharp库问题这样简单的问题,还是我的应用程序没有正确地执行此操作?

EN

回答 1

Stack Overflow用户

发布于 2021-02-26 13:48:13

这段代码看起来不正确。在ProcessImages

  • 您正在加载图像,然后对每个大小进行克隆(加载到循环之外)
  • 在将克隆保存到流中之后,您不会处理它。
  • 你总是把null还给我。

@LazZiya在缓存方面是正确的。由于您再次重复使用相同的名称,浏览器只需请求相同的缓存图像。如果在例如v=[PRODUCTRECORD_LASTWRITETIME]中添加任何querystring参数,就会得到新的图像。

为了简单起见,我建议您简单地上传源映像,并使用ImageSharp.Web中间件为您调整大小的映像提供服务。

这将自动处理源映像更改,并减少存储开销。您可以在服务器上托管源映像,并在blob存储中缓存结果。

请求变得非常简单

https://PATH_TO_IMAGE?with=[NUMBER]

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66320283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档