我想预填充 IFormFile 类型的输入

I want to pre-fill an input of type IFormFile

提问人:RayViLOz 提问时间:11/2/2023 更新时间:11/2/2023 访问量:35

问:

我正在为一些具有 ImagePath 属性的产品做一个编辑页面。当我创建产品时,我使用 IFormFile 类型的输入将图像下载到网站的 /img/products 文件夹中,它工作得很好。这里是上下文:

[HttpPost]
public async Task<IActionResult> CreateProduct(AdminCreateProductVM vm)
{
    if (!ModelState.IsValid)
        return View(vm);

    bool productAlreadyExists = _context.Products.Any(u => u.SKU == vm.SKU);

    if (productAlreadyExists)
    {
        ModelState.AddModelError(string.Empty, "Un produit avec le même SKU existe déjà.");
        return View(vm);
    }

    if (vm.Image is not null && vm.Image.Length > 0)
    {
        var webRootPath = _hostingEnvironment.WebRootPath;
        var filePath = Path.Combine(webRootPath, "img/products", vm.SKU! + ".jpg");

        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await vm.Image.CopyToAsync(stream);
        }
    }
    else
    {
        ModelState.AddModelError(string.Empty, "Veuillez sélectionner une image.");
        return View(vm);
    }

    var product = new Product()
    {
        SKU = vm.SKU,
        Name = vm.Name,
        Brand = vm.Brand,
        Model = vm.Model,
        ImagePath = "~/img/products/" + vm.SKU + ".jpg",
        WeightInGrams = vm.WeightInGrams,
        Size = vm.Size,
        Quantity = vm.Quantity,
        RetailPrice = vm.RetailPrice,
        DiscountedPrice = vm.DiscountedPrice,
        ShortDescription = vm.ShortDescription,
        FullDescription = vm.FullDescription,
        PublicationDate = (DateTime?)DateTime.Now,
        LastUpdated = (DateTime?)DateTime.Now,
        IsArchived = false
    };

    _context.Products.Add(product);
    _context.SaveChanges();

    return RedirectToAction(nameof(ManageProduct));
}

问题是,当我想修改产品时,我想用默认情况下与产品关联的图像填充 IFormFile 输入,但保留了通过上传新图像来更改它的可能性。我尝试了多种方法,以便在加载新页面时 ViewModel 包含一个 IFormFile,但都不起作用。我目前的代码(见下文)创建了 IFormFile 对象,其中包含属性方面所需的所有内容,但是在加载页面时,输入不会预先填充。

public IActionResult EditProduct(Guid id)
{
    ViewBag.Id = id;

    var toEdit = _context.Products.Find(id);

    if (toEdit is null)
        throw new ArgumentOutOfRangeException(nameof(id));

    IFormFile? toEditImage = null;
    string toEditFullImagePath = _hostingEnvironment.WebRootPath + toEdit.ImagePath![1..];

    if (System.IO.File.Exists(toEditFullImagePath))
    {
        using (FileStream fileStream = new FileStream(toEditFullImagePath, FileMode.Open, FileAccess.Read))
        {
            var fileName = Path.GetFileName(toEditFullImagePath);

            var provider = new FileExtensionContentTypeProvider();
            if (!provider.TryGetContentType(fileName, out var contentType))
            {
                contentType = "application/octet-stream"; // Utilisez un type MIME par défaut si l'extension n'est pas reconnue.
            }

            var headers = new HeaderDictionary
            {
                ["Content-Disposition"] = new StringValues("form-data; name=\"Image\"; filename=\"" + fileName + "\""),
                ["Content-Type"] = new StringValues(contentType)
            };

            toEditImage = new FormFile(fileStream, 0, fileStream.Length, fileName, fileName)
            {
                Headers = headers
            };
        }
    }
    else
    {
        ModelState.AddModelError(string.Empty, "L'image du produit n'a pas été trouvée.");
    }

    var vm = new AdminEditProductVM
    {
        SKU = toEdit.SKU,
        Name = toEdit.Name,
        Brand = toEdit.Brand,
        Model = toEdit.Model,
        Image = toEditImage,
        WeightInGrams = toEdit.WeightInGrams,
        Size = toEdit.Size,
        Quantity = toEdit.Quantity,
        RetailPrice = toEdit.RetailPrice,
        DiscountedPrice = toEdit.DiscountedPrice,
        ShortDescription = toEdit.ShortDescription,
        FullDescription = toEdit.FullDescription
    };

    return View(vm);
}

如果您需要 html 输入或 ViewModel 中的任何代码,请告诉我。先谢谢你!

C# 文件 ASP.NET-Core Web

评论


答:

0赞 Rena 11/2/2023 #1

出于安全原因,您无法以编程方式在浏览器中设置默认选择的文件。这将是一个严重的安全漏洞。用户必须通过文件输入字段手动选择文件。

你可以设置一个隐藏的输入,当你不想改变产品图片时,你可以不选择一个文件再发布到后端来判断文件是否为空。如果文件输入不为 null,则可以执行类似 did 的操作来更新值。如果为 null,则只需调用数据库更新查询。ImagePathCreateProductImagePath

评论

0赞 RayViLOz 11/2/2023
感谢您的快速回答。我可能会这样做,以便您必须选中一个复选框以表示您要修改图像,并在选中该复选框时显示输入。